Automate Job applications 🧑🏻💼📄with Chatbot, PredictLeads and ScrapegraphAI
Pull contacts, verify each address with BillionVerify, and continue to PredictLeads — only deliverable addresses get through.
Why verify before the send
Sending to invalid, risky, catch-all, or disposable addresses spikes your bounce rate and erodes sender reputation. A verification gate before the PredictLeads step removes that risk automatically — only deliverable addresses continue, the rest are flagged.
The workflow
BillionVerify — verification sits right before the send.
Node by node
- 1When chat message receivedTrigger· n8n
Starts the workflow — on a schedule, a webhook, or manually while you test.
- 2OpenAI Chat Model1Source· n8n
Provides or transforms the contact data flowing through the workflow.
- 3Context7Source· n8n
Provides or transforms the contact data flowing through the workflow.
- 4PredictLeadsSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 5Simple MemorySource· n8n
Provides or transforms the contact data flowing through the workflow.
- 6Structured Output ParserSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 7Google Gemini Chat Model1Source· n8n
Provides or transforms the contact data flowing through the workflow.
- 8Create emailSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 9When Executed by Another WorkflowTrigger· n8n
Starts the workflow — on a schedule, a webhook, or manually while you test.
- 10Send emailSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 11PredictLeads AgentSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 12Get CVSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 13ParserSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 14Verify Email (BillionVerify)Verify· billionverify
The BillionVerify node verifies the address — status (valid / invalid / risky / catch-all / role / disposable), is_deliverable, and a confidence score — before anything is sent.
- 15If list?Logic· n8n
Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.
- 16IF deliverableLogic· n8n
Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.
- 17Links ExtractorSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 18ChatSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 19Create a draftSend· n8n
Sends only to verified, deliverable addresses. Swap in your own provider node if you send elsewhere.
- 20Split OutSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 21LimitSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 22Loop Over ItemsSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 23Scrape JobSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 24Contain email?Logic· n8n
Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.
- 25Job application AgentSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 26Chat2Source· n8n
Provides or transforms the contact data flowing through the workflow.
- 27Chat1Source· n8n
Provides or transforms the contact data flowing through the workflow.
Workflow JSON
Copy or download this workflow, then import it in n8n (Workflows → Import from File / Paste). Install the BillionVerify community node first, then add your API key credential.
{
"name": "Automate Job applications 🧑🏻💼📄with Chatbot, PredictLeads and ScrapegraphAI + BillionVerify",
"nodes": [
{
"id": "9c0b9b16-0e6e-4d91-ab72-f0e93e4f220b",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
-640,
832
],
"webhookId": "b0d13c2b-fc2d-4c26-8d83-e63ef4a316d5",
"parameters": {
"options": {
"responseMode": "responseNodes"
}
},
"typeVersion": 1.4
},
{
"id": "5e084958-ce74-410b-b9ec-248157c4a398",
"name": "OpenAI Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
272,
1520
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini",
"cachedResultName": "gpt-4.1-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"id": "TefveNaDaMERl1hY",
"name": "OpenAi account (Eure)"
}
},
"typeVersion": 1.3
},
{
"id": "c0a4d07e-c795-4234-bf9b-5af8a59fdb2c",
"name": "Context7",
"type": "@n8n/n8n-nodes-langchain.mcpClientTool",
"position": [
-336,
1056
],
"parameters": {
"options": {},
"endpointUrl": "https://mcp.context7.com/mcp",
"authentication": "headerAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "8IJX1tJ5g6LPA0NR",
"name": "Context7"
}
},
"typeVersion": 1.2
},
{
"id": "0551424c-5338-40b6-8b9a-a4cd9cf095b5",
"name": "PredictLeads",
"type": "@n8n/n8n-nodes-langchain.mcpClientTool",
"position": [
-224,
1056
],
"parameters": {
"include": "selected",
"options": {},
"endpointUrl": "https://mcp.predictleads.com/",
"includeTools": [
"predictleads_job_opening",
"predictleads_discover_job_openings"
],
"authentication": "multipleHeadersAuth"
},
"credentials": {
"httpMultipleHeadersAuth": {
"id": "Wi8DEie5g9eQmTYt",
"name": "Multiple Headers PredictLeads"
}
},
"typeVersion": 1.2
},
{
"id": "141ca5a1-ba2a-407d-a9e5-d04e4314339f",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
880,
1584
],
"parameters": {
"contextWindowLength": 20
},
"typeVersion": 1.3
},
{
"id": "e70f9ff8-12a2-485f-b67c-eb0b0e3ca841",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
592,
800
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n\t\"type\": \"array\",\n\t\"properties\": {\n\t\t\"link\": {\n\t\t\t\"type\": \"string\"\n\t\t}\n\t}\n}"
},
"typeVersion": 1.3
},
{
"id": "cc86414f-a623-4a3a-9e77-96cd409f4f02",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1184,
672
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "8e57f53b-152c-4783-91d5-ae5a882471c4",
"name": "Google Gemini Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
2224,
752
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "AaNPKXAphyMzRgfA",
"name": "Google Gemini(PaLM) (Eure)"
}
},
"typeVersion": 1
},
{
"id": "7f9a2404-7177-48bd-a44f-a4da855dc04d",
"name": "Chat",
"type": "@n8n/n8n-nodes-langchain.chat",
"position": [
480,
1008
],
"webhookId": "236633f4-46a7-4ccf-b020-22fe02d6763d",
"parameters": {
"message": "={{ $json.message }}",
"options": {
"memoryConnection": true
}
},
"typeVersion": 1.2
},
{
"id": "8c843fce-a962-47fa-8b9f-c209f1d4a89c",
"name": "Create email",
"type": "@n8n/n8n-nodes-langchain.chatHitlTool",
"position": [
2432,
800
],
"webhookId": "cf7c44cf-8e3b-470b-9dfb-355d874d9ef5",
"parameters": {
"message": "=The agent wants to call {{ $tool.name }}\n\n{{ JSON.stringify($tool.parameters, null, 2) }}",
"options": {},
"approvalOptions": {
"values": {
"approvalType": "double"
}
}
},
"typeVersion": 1.2
},
{
"id": "c6906efa-6186-4399-b770-5ba3ce9184d5",
"name": "Chat1",
"type": "@n8n/n8n-nodes-langchain.chat",
"position": [
2928,
1104
],
"webhookId": "3f871230-27a9-4fa1-a8c2-d2c4b7ec4069",
"parameters": {
"message": "={{ $json.output }}",
"options": {
"memoryConnection": true
}
},
"typeVersion": 1.2
},
{
"id": "2775f022-3c08-4669-8c23-d9a5371cb598",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"disabled": true,
"position": [
960,
672
],
"parameters": {},
"typeVersion": 1
},
{
"id": "b305684c-8c7f-4a95-907c-a35dba17450a",
"name": "When Executed by Another Workflow",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
2400,
1552
],
"parameters": {
"workflowInputs": {
"values": [
{
"name": "emailTo"
},
{
"name": "subject"
},
{
"name": "text"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "7291f889-6a60-4e3b-8a7f-1a75b1ffa5c0",
"name": "Create a draft",
"type": "n8n-nodes-base.gmail",
"position": [
2848,
1552
],
"webhookId": "e220a165-b52c-49df-b201-c25f3bbfd278",
"parameters": {
"message": "={{ $('When Executed by Another Workflow').item.json.text }}",
"options": {
"sendTo": "={{ $('When Executed by Another Workflow').item.json.emailTo }}",
"attachmentsUi": {
"attachmentsBinary": [
{
"property": "data"
}
]
}
},
"subject": "={{ $('When Executed by Another Workflow').item.json.subject }}",
"resource": "draft"
},
"credentials": {
"gmailOAuth2": {
"id": "nyuHvSX5HuqfMPlW",
"name": "Gmail account (n3w.it)"
}
},
"typeVersion": 2.2
},
{
"id": "0d6ff9a6-3e14-4c04-957f-38512efed081",
"name": "Job application Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2288,
592
],
"parameters": {
"text": "=Email annuncio: {{ $json.result.email }}\nPosizione aperta annuncio: {{ $json.result.position }}\n\nTesto annuncio: {{ $json.result.text }}",
"options": {
"systemMessage": "You are an expert in job applications and professional email communication.\n\nYour task is to generate a job application email based on the information provided in each request.\n\nYou MUST use the tool **\"Create email\"** to generate:\n\n* The subject line of the email\n* The full body text of the email\n\nAlways ensure the email is:\n\n* Professional and well-structured\n* Clear and concise\n* Tailored to the job position provided\n* Written in a confident but polite tone\n\nUse the following personal information of the candidate when generating the email:\n\nName: XXX\nBorn: XXX\nResident: XXX\nOther: Dynamic person, strong problem-solving skills\n\nDo not invent additional personal details unless explicitly provided.\nIf any required information is missing, write the email using only the available data.\n\nThe final output must be ready to send.\n"
},
"promptType": "define"
},
"typeVersion": 3.1
},
{
"id": "53913e61-d146-4ad5-8c3d-ecc9fa46ba09",
"name": "Send email",
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"position": [
2384,
1008
],
"parameters": {
"workflowId": {
"__rl": true,
"mode": "id",
"value": "=ZhpFW0At1ondVya0",
"cachedResultUrl": "/workflow/=ZhpFW0At1ondVya0"
},
"workflowInputs": {
"value": {
"text": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('text', ``, 'string') }}",
"emailTo": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('emailTo', ``, 'string') }}",
"subject": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('subject', ``, 'string') }}"
},
"schema": [
{
"id": "emailTo",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "emailTo",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "subject",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "subject",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "text",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "text",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
}
},
"typeVersion": 2.2
},
{
"id": "c9a51e83-6dea-4738-af93-350c7d3d0003",
"name": "Get CV",
"type": "n8n-nodes-base.httpRequest",
"position": [
2624,
1552
],
"parameters": {
"url": "https://xxx/cv.pdf",
"options": {}
},
"typeVersion": 4.4
},
{
"id": "7078edd1-57b2-4d0b-bd93-90a200cddfde",
"name": "Scrape Job",
"type": "n8n-nodes-scrapegraphai.scrapegraphAi",
"position": [
1488,
688
],
"parameters": {
"userPrompt": "Extract the email address to which applications should be sent. If no email address is available, return \"null\". Also extract the open job position.",
"websiteUrl": "={{ $json.output }}",
"outputSchema": "{\n \"type\": \"object\",\n \"title\": \"ProductSchema\",\n \"properties\": {\n \"email\": {\n \"type\": \"string\",\n \"title\": \"email\",\n \"description\": \"Email to send CV\"\n },\n \"position\": {\n \"type\": \"string\",\n \"title\": \"position\",\n \"description\": \"Open job position\"\n },\n \"text\": {\n \"type\": \"string\",\n \"title\": \"text\",\n \"description\": \"Complete text\"\n }\n },\n \"required\": [\"email\", \"position\", \"text\"]\n}",
"useOutputSchema": true
},
"credentials": {
"scrapegraphAIApi": {
"id": "EOxCPnl9IynxgpyB",
"name": "ScrapegraphAI account"
}
},
"typeVersion": 1
},
{
"id": "0752da9b-d89b-46ba-8afe-8849356fa380",
"name": "Contain email?",
"type": "n8n-nodes-base.if",
"position": [
1760,
688
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "846b1ced-a841-4fa7-bd13-5f893df93225",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.result.email }}",
"rightValue": "=@"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "ffb70025-0e02-46ba-b533-7eaed5aced2d",
"name": "Links Extractor",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
448,
592
],
"parameters": {
"text": "={{ $json.message }}",
"batching": {},
"messages": {
"messageValues": [
{
"message": "Extract the links"
}
]
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.9
},
{
"id": "32df0f47-36fc-4f6c-9686-1e93d013e537",
"name": "PredictLeads Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-416,
832
],
"parameters": {
"options": {
"systemMessage": "You are an AI automation agent running inside an n8n workflow.\n\nYour mission is to help the workflow by answering user requests and orchestrating tool usage when needed.\nAlways follow the rules below exactly.\n\nTOOL USAGE RULES (CRITICAL)\n1) For any request involving company research (e.g., information about a company, firmographics, funding, headcount, industry, competitors, subsidiaries, acquisitions, locations, executives, news about a company, etc.):\n - You MUST consult the tool \"Context7\" FIRST.\n - Only after using Context7, if additional or verified company data is needed, you MAY call \"PredictLeads\".\n - Never call PredictLeads before Context7 for company research requests.\n\n2) If the request is NOT company research, you may decide whether tools are necessary. Do not use tools unnecessarily.\n\nOUTPUT FORMAT (MANDATORY)\nYou MUST always output a single valid JSON object, nothing else (no markdown, no extra text).\n\nThe JSON schema must be:\n{\n \"list\": boolean,\n \"output\": string\n}\n\n- \"list\" must be set to true ONLY when the result is a list from:\n a) a job search / job listings request, OR\n b) a list of companies, OR\n c) data originating from PredictLeads (including lists of results returned by PredictLeads).\n- Otherwise set \"list\" to false.\n\n- \"output\" must contain the COMPLETE final message to the user (fully formed, ready to be shown).\n Include all relevant details, steps, and results in plain text.\n\nGENERAL BEHAVIOR\n- Be clear, concise, and actionable.\n- If information is uncertain, state assumptions explicitly.\n- If the user request is ambiguous, make a best-effort interpretation and proceed, minimizing follow-up questions.\n- Do not expose internal tool call details unless the user explicitly asks for them."
}
},
"typeVersion": 3.1
},
{
"id": "55457900-e1b9-4a94-96c4-8de46a91af4c",
"name": "Parser",
"type": "n8n-nodes-base.code",
"position": [
-64,
832
],
"parameters": {
"jsCode": "for (const item of $input.all()) {\n try {\n let rawOutput = item.json.output;\n\n rawOutput = String(rawOutput)\n .replace(/```json\\n?/gi, \"\")\n .replace(/```\\n?/g, \"\")\n .trim();\n\n rawOutput = rawOutput.replace(/\\\\'/g, \"'\");\n\n const parsedData = JSON.parse(rawOutput);\n const cleanData = parsedData.properties || parsedData;\n\n // Caso 1: output \"message\" (come nel tuo esempio)\n if (typeof cleanData.message === \"string\" && cleanData.message.trim()) {\n item.json = {\n list: !!cleanData.list,\n message: cleanData.message.trim(),\n };\n continue;\n }\n\n // Caso 2: output \"card\" (title/prompt) come nello script originale\n if (!cleanData.title || !cleanData.prompt) {\n throw new Error(\"Campi obbligatori mancanti: (message) oppure (title e prompt)\");\n }\n\n item.json = {\n title: String(cleanData.title).trim(),\n style: cleanData.style ? String(cleanData.style).trim() : \"\",\n prompt: String(cleanData.prompt).trim(),\n negativeTags: cleanData.negativeTags ? String(cleanData.negativeTags).trim() : \"\",\n };\n } catch (error) {\n throw new Error(\"Errore nel parsing JSON: \" + error.message);\n }\n}\n\nreturn $input.all();"
},
"typeVersion": 2
},
{
"id": "a39c4a07-c0fb-46d1-b366-4945e39520a9",
"name": "Split Out",
"type": "n8n-nodes-base.splitOut",
"position": [
736,
672
],
"parameters": {
"options": {},
"fieldToSplitOut": "output"
},
"typeVersion": 1
},
{
"id": "0387d1ca-d76c-4d95-a3cc-c24e69788fb4",
"name": "Chat2",
"type": "@n8n/n8n-nodes-langchain.chat",
"position": [
1968,
880
],
"webhookId": "3f871230-27a9-4fa1-a8c2-d2c4b7ec4069",
"parameters": {
"message": "=This ad doesn't contain an email address. You'll likely need to apply directly from the website. Here's the link: {{ $json.website_url }}",
"options": {
"memoryConnection": true
}
},
"typeVersion": 1.2
},
{
"id": "8c1b5b5b-7aaa-4dad-b7ec-2b53d967d3a0",
"name": "If list?",
"type": "n8n-nodes-base.if",
"position": [
160,
832
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "ee88996d-2d85-4692-a6a5-f978bd1674da",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.list }}",
"rightValue": false
}
]
}
},
"typeVersion": 2.3
},
{
"id": "0f3b659a-bee8-4cb4-883d-13a909b348b9",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-496,
96
],
"parameters": {
"width": 800,
"height": 544,
"content": "## Chatbot Job Apply System with PredictLeads & Scrapegraph AI\n\nThis Chatbot automates the process of discovering job openings and generating tailored job application emails. \n\nIt combines AI agents, web scraping, and email drafting to streamline job applications.\n\n### How it works:\n\nThis workflow starts from a Chat Trigger and uses a LangChain-based PredictLeads Agent to interpret user intent and optionally perform company research via Context7 and PredictLeads. The agent output is parsed into structured JSON to determine whether to return a direct response or extract and process job URLs. For each job link, the workflow scrapes position details and contact email using ScrapegraphAI, then conditionally generates a tailored application email via a Gemini-powered agent. The email is formatted using a dedicated tool and a draft is created in Gmail with the CV attached, while maintaining human-in-the-loop approval and structured error handling.\n\n### Setup steps:\n\nConfigure required credentials for OpenAI, Google Gemini, Context7, PredictLeads (with appropriate headers), ScrapegraphAI, and Gmail OAuth2. Ensure the CV is publicly accessible via the HTTP Request node and verify the “Send email” workflow ID matches the current workflow. Optionally customize system prompts in the PredictLeads Agent and Job Application Agent to include candidate-specific information. The Chat Trigger and Simple Memory nodes require no setup but must remain correctly connected to preserve conversation context and workflow continuity.\n"
},
"typeVersion": 1
},
{
"id": "580d8879-5cd5-4d0c-8e7a-9edf9bd88bf2",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-496,
688
],
"parameters": {
"color": 7,
"width": 800,
"height": 592,
"content": "## STEP 1 - PredictLeads Agent \n**[PredictLeads](https://predictleads.com/) Agent processes the request** – A LangChain agent determines the user's intent. If the request involves **company research**, it first queries **Context7**, then optionally **PredictLeads** for deeper data."
},
"typeVersion": 1
},
{
"id": "97d26b08-34f2-4e0e-ab89-ce696fdb7074",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
480
],
"parameters": {
"color": 7,
"width": 704,
"height": 480,
"content": "## STEP 2 - Extract Links\nExtract job posting URLs from the user's input."
},
"typeVersion": 1
},
{
"id": "e03b3653-a8d4-44c9-bdf0-ce58fb1dedd2",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1152,
480
],
"parameters": {
"color": 7,
"width": 736,
"height": 480,
"content": "## STEP 3 - Scrape Job\nThe Scrape Job node (powered by [ScrapegraphAI](https://dashboard.scrapegraphai.com/?via=n3witalia)) extracts: Email address to send the application to, Job position title, Full job description text"
},
"typeVersion": 1
},
{
"id": "ad56f348-b8de-410e-ae29-4aa263d52898",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1920,
480
],
"parameters": {
"color": 7,
"width": 880,
"height": 672,
"content": "## STEP 4 - Job Application Agent\nA Gemini-powered agent generates a professional email using: Candidate's personal info (name, location, skills), Job position and description. A tool (Create email) to format the subject and body"
},
"typeVersion": 1
},
{
"id": "f70961ce-02a9-48e0-8965-bc6f1f81996e",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2320,
1424
],
"parameters": {
"color": 7,
"width": 880,
"height": 320,
"content": "## STEP 5 - Send email with CV\n The agent triggers the Send email workflow, which: Fetches the CV from a public URL, Creates a draft in Gmail with the CV attached"
},
"typeVersion": 1
},
{
"id": "db743866-7b48-40b4-a891-9be23b60429d",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
-304
],
"parameters": {
"color": 7,
"width": 736,
"height": 736,
"content": "## MY NEW YOUTUBE CHANNEL\n👉 [Subscribe to my new **YouTube channel**](https://youtube.com/@n3witalia). Here I’ll share videos and Shorts with practical tutorials and **FREE templates for n8n**.\n\n[](https://youtube.com/@n3witalia)"
},
"typeVersion": 1
},
{
"parameters": {
"operation": "verify",
"email": "={{ $json.email || $json.Email }}",
"additionalOptions": {}
},
"type": "n8n-nodes-billionverify.billionVerify",
"typeVersion": 1,
"position": [
2488,
1552
],
"name": "Verify Email (BillionVerify)",
"credentials": {
"billionVerifyApi": {
"id": "",
"name": "BillionVerify account"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "is-deliverable",
"leftValue": "={{ $json.is_deliverable }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
]
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
2668,
1552
],
"name": "IF deliverable"
}
],
"connections": {
"Chat1": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Chat2": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Limit": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Get CV": {
"main": [
[
{
"node": "Verify Email (BillionVerify)",
"type": "main",
"index": 0
}
]
]
},
"Parser": {
"main": [
[
{
"node": "If list?",
"type": "main",
"index": 0
}
]
]
},
"Context7": {
"ai_tool": [
[
{
"node": "PredictLeads Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"If list?": {
"main": [
[
{
"node": "Links Extractor",
"type": "main",
"index": 0
}
],
[
{
"node": "Chat",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
]
]
},
"Scrape Job": {
"main": [
[
{
"node": "Contain email?",
"type": "main",
"index": 0
}
]
]
},
"Send email": {
"ai_tool": [
[
{
"node": "Create email",
"type": "ai_tool",
"index": 0
}
]
]
},
"Create email": {
"ai_tool": [
[
{
"node": "Job application Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"PredictLeads": {
"ai_tool": [
[
{
"node": "PredictLeads Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "PredictLeads Agent",
"type": "ai_memory",
"index": 0
},
{
"node": "Job application Agent",
"type": "ai_memory",
"index": 0
},
{
"node": "Chat1",
"type": "ai_memory",
"index": 0
},
{
"node": "Chat",
"type": "ai_memory",
"index": 0
},
{
"node": "Chat2",
"type": "ai_memory",
"index": 0
}
]
]
},
"Contain email?": {
"main": [
[
{
"node": "Job application Agent",
"type": "main",
"index": 0
}
],
[
{
"node": "Chat2",
"type": "main",
"index": 0
}
]
]
},
"Links Extractor": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Scrape Job",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model1": {
"ai_languageModel": [
[
{
"node": "PredictLeads Agent",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Links Extractor",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"PredictLeads Agent": {
"main": [
[
{
"node": "Parser",
"type": "main",
"index": 0
}
]
]
},
"Job application Agent": {
"main": [
[
{
"node": "Chat1",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Links Extractor",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Google Gemini Chat Model1": {
"ai_languageModel": [
[
{
"node": "Job application Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "PredictLeads Agent",
"type": "main",
"index": 0
}
]
]
},
"When Executed by Another Workflow": {
"main": [
[
{
"node": "Get CV",
"type": "main",
"index": 0
}
]
]
},
"Verify Email (BillionVerify)": {
"main": [
[
{
"node": "IF deliverable",
"type": "main",
"index": 0
}
]
]
},
"IF deliverable": {
"main": [
[
{
"node": "Create a draft",
"type": "main",
"index": 0
}
],
[]
]
}
},
"settings": {
"binaryMode": "separate",
"availableInMCP": false,
"executionOrder": "v1"
}
}When to use this
- Cleaning a list before a PredictLeads send or sync.
- Protecting PredictLeads deliverability and sender reputation.
- Keeping bounce rates low so your sending is never throttled.
FAQ
Why verify before sending in PredictLeads?
Verifying first keeps your bounce rate low, which protects your sender reputation and your results.
How do I import this workflow?
Download the JSON, then in n8n go to Workflows → Import from File (or paste it). Install the BillionVerify community node and add your API key credential.
What happens to risky or catch-all addresses?
They are routed to the false branch and excluded from the send. You decide whether to retry, review, or drop them.
Add verification to your workflow
Create a free account, grab your API key, and stop bounces before they happen.
Get started free