AutomationFlowsAI & RAG › Automated B2b Prospecting with Rapidapi, Hunter.io, Gpt & Gmail

Automated B2b Prospecting with Rapidapi, Hunter.io, Gpt & Gmail

ByJimmy Gay @jimmyjoe on n8n.io

Automate your B2B prospecting by finding local businesses and sending AI-personalized outreach emails to qualified contacts.

Event trigger★★★★☆ complexityAI-powered21 nodesOpenAI ChatForm TriggerHTTP RequestHunterAgentGmailGoogle Tasks
AI & RAG Trigger: Event Nodes: 21 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → Form Trigger 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
{
  "nodes": [
    {
      "id": "5aeaafb8-ecf0-482f-aff8-07cac51b5fef",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1160,
        160
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-nano-2025-08-07",
          "cachedResultName": "gpt-5-nano-2025-08-07"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c6c57e72-d4d3-4421-b915-20369d4be3c5",
      "name": "compagny_search",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -380,
        20
      ],
      "parameters": {
        "options": {},
        "formTitle": "compagny_search",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Business Sector",
              "placeholder": "[ engineering ]",
              "requiredField": true
            },
            {
              "fieldLabel": "city",
              "placeholder": "[ London ]"
            },
            {
              "fieldLabel": "Number of Leads",
              "placeholder": "[ 20 ]"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "b13ac03b-4bb5-4264-91b3-e0c03765bc94",
      "name": "Search Local Businesses",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        60,
        20
      ],
      "parameters": {
        "url": "https://local-business-data.p.rapidapi.com/search",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "query",
              "value": "={{ $json[\"Business Sector\"] }} {{ $json.city }}"
            },
            {
              "name": "limit",
              "value": "={{ $json[\"Number of Leads\"] }}"
            },
            {
              "name": "zoom",
              "value": "13"
            },
            {
              "name": "language",
              "value": "fr"
            },
            {
              "name": "region",
              "value": "fr"
            },
            {
              "name": "extract_emails_and_contacts",
              "value": "false"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "x-rapidapi-host",
              "value": "local-business-data.p.rapidapi.com"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "66a87c7e-b194-4358-8b54-2ed949bd87bd",
      "name": "Split Out Businesses",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -140,
        260
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "data"
      },
      "typeVersion": 1
    },
    {
      "id": "d5228b9a-a0ac-4366-83d2-6143f5fcd7dc",
      "name": "If Website Exists",
      "type": "n8n-nodes-base.if",
      "position": [
        80,
        260
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b86f0175-b755-49c1-becc-e3e6ca4747b4",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.website }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e2298683-1c78-461d-a6f3-a51ad5760ff9",
      "name": "Scrape Website",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        380,
        -180
      ],
      "parameters": {
        "url": "={{ $json.website }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {}
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d8319ac4-a8bc-4659-93c3-d762b2e60c1e",
      "name": "If Scraping Succeeded",
      "type": "n8n-nodes-base.if",
      "position": [
        420,
        40
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "324f2d98-a187-43bd-be7b-2ce74333d1a9",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ !$json.hasOwnProperty('error') }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "ef9347c3-543d-4c80-aa27-ab01989197b1",
      "name": "Extract Title & Description",
      "type": "n8n-nodes-base.html",
      "position": [
        620,
        -200
      ],
      "parameters": {
        "options": {},
        "operation": "extractHtmlContent",
        "extractionValues": {
          "values": [
            {
              "key": "scraped_title",
              "cssSelector": "title"
            },
            {
              "key": "scraped_description",
              "attribute": "content",
              "cssSelector": "meta[name=\"description\"]",
              "returnValue": "attribute"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "485ba79a-899f-45d5-a701-51a1ab8c678a",
      "name": "Find Contacts (Hunter)",
      "type": "n8n-nodes-base.hunter",
      "position": [
        620,
        40
      ],
      "parameters": {
        "limit": 10,
        "domain": "={{ $('Split Out Businesses').item.json.tld }}",
        "filters": {}
      },
      "credentials": {
        "hunterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "45d46c83-22a5-45ab-9151-ea5eb48a136e",
      "name": "Split Out Contacts",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        840,
        -200
      ],
      "parameters": {
        "include": "allOtherFields",
        "options": {},
        "fieldToSplitOut": "value"
      },
      "typeVersion": 1
    },
    {
      "id": "82e9a446-fdf9-44b8-832d-ed0cf4329dbe",
      "name": "If Contact Is Valid",
      "type": "n8n-nodes-base.if",
      "position": [
        840,
        60
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "7e49f6e9-2024-4bb7-9010-76c14446f6fd",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.first_name }}",
              "rightValue": ""
            },
            {
              "id": "1405a866-f79f-4293-88f1-cde8fa48e0ea",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Find Contacts (Hunter)').item.json.verification.status }}",
              "rightValue": "valid"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "64081640-91a1-4110-a0b7-688f8ed458e4",
      "name": "Generate Email Body (AI)",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1160,
        -40
      ],
      "parameters": {
        "text": "=Here is the information about your target :\n\n- Contact firstname : {{ $json.first_name }}\n- Jobtittle : {{ $json.position }}\n- Compagny name: {{ $('If Website Exists').item.json.name }}\n- Website Tittle : \"{{ $('Extract Title & Description').item.json.scraped_title }}\"\n- Website Description : \"{{ $('Extract Title & Description').item.json.scraped_description }}\"\n\n\n",
        "options": {
          "systemMessage": "=You are an expert in B2B sales prospecting, writing impactful outreach emails for the company [ Your_Compagny ] ([YOUR_COMPAGNY_WEBSITE]). \n\nYour mission: Write a short (about 100 words), friendly, and professional email. The goal is to generate interest for a potential project in automation, technical SEO, and customer acquisition campaigns. \nStart with a personalized hook based on their website's title or description. Show you've done your research. \nAddress the person according to their job title. \n\nEnd with a simple, open-ended question to encourage a reply. The output must ONLY be the email body in plain text. Do NOT start with 'Hello [First Name],' and do NOT sign off at the end."
        },
        "promptType": "define"
      },
      "typeVersion": 2
    },
    {
      "id": "c21fff57-d1c0-444a-96b8-42e9d9efcb43",
      "name": "Format AI Output",
      "type": "n8n-nodes-base.code",
      "position": [
        1560,
        -40
      ],
      "parameters": {
        "jsCode": "// On r\u00e9cup\u00e8re tous les items en entr\u00e9e sous forme de tableau.\n// Dans votre cas, ce sera un tableau avec un seul item.\nconst items = $items();\n\n// On utilise .map() pour cr\u00e9er un nouveau tableau avec les items modifi\u00e9s.\n// C'est la m\u00e9thode la plus propre et la plus s\u00fbre.\nconst newItems = items.map(item => {\n  // On r\u00e9cup\u00e8re les donn\u00e9es JSON de l'item en cours\n  const json = item.json;\n  \n  // On r\u00e9cup\u00e8re le texte brut g\u00e9n\u00e9r\u00e9 par l'IA, qui est dans le champ 'output'\n  const rawText = json.output;\n\n  // On initialise une variable pour le texte format\u00e9\n  let formattedText = \"\";\n\n  // On v\u00e9rifie que le texte existe bien avant de le traiter\n  if (rawText && typeof rawText === 'string') {\n    const sentences = rawText.match(/[^.!?]+[.!?]*/g) || [];\n    formattedText = sentences\n      .map(s => s.trim())\n      .filter(s => s.length > 0)\n      .join('\\n\\n');\n  }\n\n  // On retourne un NOUVEL objet item, format\u00e9 comme n8n l'attend.\n  // On copie toutes les anciennes donn\u00e9es (...json) et on ajoute notre nouveau champ.\n  return {\n    json: {\n      ...json,\n      formatted_text: formattedText\n    }\n  };\n});\n\n// On retourne le nouveau tableau d'items. C'est la sortie attendue par n8n.\nreturn newItems;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "f2541c58-120a-48a1-a8ff-4e2429b0f377",
      "name": "Assemble Final Email",
      "type": "n8n-nodes-base.set",
      "position": [
        1340,
        220
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0d2f01ce-0d10-41c0-99ff-2ac2ba70abef",
              "name": "email_subject",
              "type": "string",
              "value": "=Developing the business of {{ $('If Website Exists').item.json.name }}"
            },
            {
              "id": "fbcfb7dc-53f4-4653-8464-dc26fd190c0f",
              "name": "email_body",
              "type": "string",
              "value": "=Hi {{ $('Split Out Contacts').item.json.first_name }},  \n\n{{ $json.formatted_text }}\n\nDear,\n"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6d25c563-2351-4f78-96ac-00e750197ffc",
      "name": "Send Email (Gmail)",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1580,
        220
      ],
      "parameters": {
        "sendTo": "={{ $('Find Contacts (Hunter)').item.json.value }}",
        "message": "={{ $json.email_body }}",
        "options": {},
        "subject": "={{ $json.email_subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "074804f9-e975-4a2a-90b9-de682d0e68cd",
      "name": "Set Task Data",
      "type": "n8n-nodes-base.set",
      "position": [
        440,
        660
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "15424ccb-ff6d-4aa4-83d6-247a55023ffe",
              "name": "phone_number",
              "type": "string",
              "value": "={{ $json.phone_number }}"
            },
            {
              "id": "7f78f42f-414a-4e2e-b493-3c35ad9586bd",
              "name": "compagny_name",
              "type": "string",
              "value": "={{ $json.name }}"
            },
            {
              "id": "6a561bd7-42c2-4078-99d7-706f41f41636",
              "name": "adress",
              "type": "string",
              "value": "={{ $json.full_address }}"
            },
            {
              "id": "6682a516-030d-40b4-b14a-fd54fa3222a0",
              "name": "type",
              "type": "string",
              "value": "={{ $json.type }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "df43e879-9b1c-4eb1-8ee4-c2e21a6db8a4",
      "name": "Create Google Task for Follow-up",
      "type": "n8n-nodes-base.googleTasks",
      "position": [
        1060,
        660
      ],
      "parameters": {
        "task": "MTI3OTk4MTA0ODg4NDY1ODkwMTc6MDow",
        "title": "=Appeler {{ $json.compagny_name }} au {{ $json.phone_number }} Pour cr\u00e9ation de site web ! ",
        "additionalFields": {}
      },
      "credentials": {
        "googleTasksOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ef60a1bc-b42f-4e9a-a151-dc61b0b91616",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        -420
      ],
      "parameters": {
        "width": 1560,
        "height": 620,
        "content": "## Quick Start & Required Setup\n\n\n### Welcome! This workflow finds local businesses, identifies contacts, and sends them a personalized email.\n\n**Action Required - Setup Credentials**:\nBefore you start, you must connect your own accounts. This workflow requires:\n\n**RapidAPI**: On the Search Local Businesses node, add a \"Header Auth\" credential with your x-rapidapi-key.\n\n**Hunter.io**: On the Find Contacts (Hunter) node, add your \"Hunter Credential\".\n\n**OpenAI**: On the OpenAI Chat Model node, add your \"OpenAI Credential\".\n\n**Gmail**: On the Send Email (Gmail) node, add your \"Gmail Credential\".\n\n**Google Tasks**: On the Create Google Task for Follow-up node, add your \"Google Tasks Credential\".\n\nOnce set up, fill this form and click \"Test Workflow\" to run it."
      },
      "typeVersion": 1
    },
    {
      "id": "e9eabba1-a027-49c4-8b55-554325be9bea",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1020,
        -420
      ],
      "parameters": {
        "color": 4,
        "width": 980,
        "height": 960,
        "content": "## Customize Your Outreach\n\n### This is where you personalize your sales pitch.\n\n**Action Required - Customize Content :**\n\nAI Prompt: In this node's options, edit the \"System Message\" to describe your company, your website, and your services. This is crucial for generating relevant emails.\n\nEmail Signature: Go to the Assemble Final Email node and edit the email_body expression to add your professional signature."
      },
      "typeVersion": 1
    },
    {
      "id": "3b6ca027-27ce-4843-9258-d3bd1872b7df",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        220
      ],
      "parameters": {
        "color": 5,
        "width": 1560,
        "height": 320,
        "content": "## Workflow Logic Overview\n\n### How this workflow operates:\n\nIt searches for businesses using your criteria.\n\nIf a website exists, it scrapes the title and description for context.\n\nIt then finds valid contacts for that company using Hunter.io.\n\nAn AI generates a personalized email, which is then sent.\n\nIf no website is found, a task is created in Google Tasks for manual follow-up."
      },
      "typeVersion": 1
    },
    {
      "id": "355635c9-3ed0-49a8-aec4-731111c3dae5",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        560
      ],
      "parameters": {
        "width": 2560,
        "height": 320,
        "content": "## Configure Manual Follow-up\n\n### This node handles leads that require manual action (e.g., no website found).\n\n**Action Required :**\n\nEnsure your Google account is connected.\n\nImportant: You must select your own \"Task List\" from the dropdown menu for this node to work correctly."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Set Task Data": {
      "main": [
        [
          {
            "node": "Create Google Task for Follow-up",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape Website": {
      "main": [
        [
          {
            "node": "If Scraping Succeeded",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "compagny_search": {
      "main": [
        [
          {
            "node": "Search Local Businesses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format AI Output": {
      "main": [
        [
          {
            "node": "Assemble Final Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Website Exists": {
      "main": [
        [
          {
            "node": "Scrape Website",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set Task Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Email Body (AI)",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Split Out Contacts": {
      "main": [
        [
          {
            "node": "If Contact Is Valid",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Contact Is Valid": {
      "main": [
        [
          {
            "node": "Generate Email Body (AI)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assemble Final Email": {
      "main": [
        [
          {
            "node": "Send Email (Gmail)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out Businesses": {
      "main": [
        [
          {
            "node": "If Website Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Scraping Succeeded": {
      "main": [
        [
          {
            "node": "Extract Title & Description",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find Contacts (Hunter)": {
      "main": [
        [
          {
            "node": "Split Out Contacts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Local Businesses": {
      "main": [
        [
          {
            "node": "Split Out Businesses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Email Body (AI)": {
      "main": [
        [
          {
            "node": "Format AI Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Title & Description": {
      "main": [
        [
          {
            "node": "Find Contacts (Hunter)",
            "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

Automate your B2B prospecting by finding local businesses and sending AI-personalized outreach emails to qualified contacts.

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

This workflow automates end-to-end contract and invoice management using AI intelligence. It processes proposals through intelligent contract generation, approval workflows, and automated invoicing. O

Form Trigger, Data Table, Agent +4
AI & RAG

Automates SaaS operations by consolidating user management, AI-driven support triage, analytics, and billing into one unified system. User signups flow through registration, support requests route via

Form Trigger, Data Table, Agent +7
AI & RAG

The workflow runs every hour with a randomized delay of 5–20 minutes to help distribute load. It records the exact date and time a lead is emailed so you can track outreach. Follow-ups are automatical

Google Sheets, Agent, OpenAI Chat +5
AI & RAG

This n8n workflow automates turning short user ideas into production-ready real-estate marketing assets (photorealistic images and optional 360° videos). A form submission seeds a prompt board → an LL

Form Trigger, Google Sheets, Agent +6
AI & RAG

This workflow automatically analyzes a website for UX and SEO quality. It uses Airtop for realistic web scraping, OpenAI for structured evaluation of metadata (title, description, and overall SEO sign

Airtop Tool, Form Trigger, OpenAI Chat +6