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 →
{
"name": "Lead Qualification AI \u2014 Multi-Niche Demo",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "lead-qualification",
"responseMode": "lastNode",
"options": {}
},
"id": "d1f7a2b3-8c4e-4a1f-9d2e-3f5b6c7a8d9e",
"name": "Incoming Lead Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
250,
300
]
},
{
"parameters": {
"jsCode": "// Parse incoming message\nconst body = $input.item.json;\nconst message = (body.text || body.message || body.body || '').trim();\nconst leadId = body.from || body.sender || body.wa_id || body.lead_id || ('lead_' + Date.now());\nconst leadName = body.name || body.profile?.name || body.sender_name || 'Prospect';\nconst source = body.source || 'whatsapp';\nconst conversationState = body.state || body.conversation_state || {};\n\nreturn {\n lead_id: leadId,\n lead_name: leadName,\n message: message,\n source: source,\n timestamp: new Date().toISOString(),\n conversation_state: conversationState,\n message_count: (conversationState.message_count || 0) + 1\n};"
},
"id": "e2a8b3c4-9d5f-5b2f-ae3f-4c6d7e8f9a0b",
"name": "Parse Lead Message",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
450,
300
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.deepseek.com/v1/chat/completions",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer {{$env.DEEPSEEK_API_KEY}}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": []
},
"specifyBody": "json",
"jsonBody": "{\n \"model\": \"deepseek-chat\",\n \"temperature\": 0.4,\n \"max_tokens\": 500,\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are an AI lead qualification agent for PersiAi, an AI automation agency. We automate business operations: WhatsApp receptionists, lead gen, CRM, reviews, invoicing, scheduling \u2014 serving dental, medical, restaurants, hotels, real estate, law, salons, gyms, auto, e-commerce.\\n\\nYOUR JOB: Natural, friendly conversation to qualify this lead. Casual English with Arabic warmth (\u062d\u0628\u064a\u0628\u064a, \u064a\u0627\u0644\u063a\u0627\u0644\u064a) for Arabic speakers. NEVER sound robotic.\\n\\nQUALIFYING QUESTIONS (1-2 per message, don't interrogate):\\n1. Name and business?\\n2. Industry?\\n3. Biggest operational headache?\\n4. Size/locations?\\n5. Budget? (<150 KWD, 150-350, 350-650, 650+)\\n6. Timeline?\\n\\nRULES:\\n- First message: greet + ask name/business\\n- Acknowledge answers, ask next natural question\\n- After 3+ answers: summarize + score\\n- Keep replies 1-3 sentences (WhatsApp style)\\n\\nSCORING:\\n- HOT: budget 350+, urgent, multi-location\\n- WARM: budget 150-350, this month\\n- COLD: budget <150 or just browsing\\n\\nRESPOND IN JSON ONLY:\\n{\\\"reply\\\": \\\"your natural reply\\\", \\\"score\\\": \\\"hot|warm|cold|pending\\\", \\\"qualification\\\": {\\\"name\\\": null, \\\"business\\\": null, \\\"industry\\\": null, \\\"pain_point\\\": null, \\\"size\\\": null, \\\"budget\\\": null, \\\"timeline\\\": null}, \\\"conversation_state\\\": {}}\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Message from {{ $('Parse Lead Message').item.json.lead_name }}:\\n\\\"{{ $('Parse Lead Message').item.json.message }}\\\"\\n\\nPrevious info: {{ JSON.stringify($('Parse Lead Message').item.json.conversation_state || {}) }}\"\n }\n ]\n}",
"options": {}
},
"id": "f3b9c4d5-ae6f-6c3f-bf4d-5d7e8f9a0b1c",
"name": "AI Qualify & Score Lead",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
650,
300
]
},
{
"parameters": {
"jsCode": "const aiResponse = $input.item.json;\nconst rawContent = aiResponse.choices?.[0]?.message?.content || '{}';\n\nlet parsed;\ntry {\n const cleaned = rawContent.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n parsed = JSON.parse(cleaned);\n} catch(e) {\n parsed = { reply: \"Hey! Could you tell me about your business?\", score: \"pending\", qualification: {} };\n}\n\nconst prevQual = $('Parse Lead Message').item.json.conversation_state?.qualification || {};\nconst qualification = { ...prevQual, ...parsed.qualification };\nObject.keys(qualification).forEach(k => { if (qualification[k] === null) delete qualification[k]; });\n\nconst score = parsed.score || 'pending';\nconst leadData = $('Parse Lead Message').item.json;\n\nreturn {\n lead_id: leadData.lead_id,\n lead_name: leadData.lead_name,\n source: leadData.source,\n message: leadData.message,\n reply: parsed.reply,\n score: score,\n qualification: qualification,\n conversation_state: {\n message_count: leadData.message_count,\n collected_fields: Object.keys(qualification),\n qualification: qualification,\n last_score: score\n },\n timestamp: new Date().toISOString()\n};"
},
"id": "a4c0d5e6-bf7f-7d4f-cf5e-6e8f9a0b1c2d",
"name": "Format Qualification Result",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
850,
300
]
},
{
"parameters": {
"method": "POST",
"url": "http://host.docker.internal:8765/append",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": []
},
"specifyBody": "json",
"jsonBody": "{\n \"values\": [\n [\n \"{{ $('Format Qualification Result').item.json.timestamp }}\",\n \"{{ $('Format Qualification Result').item.json.lead_id }}\",\n \"{{ $('Format Qualification Result').item.json.qualification.name || $('Format Qualification Result').item.json.lead_name }}\",\n \"{{ $('Format Qualification Result').item.json.qualification.business || '' }}\",\n \"{{ $('Format Qualification Result').item.json.qualification.industry || '' }}\",\n \"{{ $('Format Qualification Result').item.json.qualification.pain_point || '' }}\",\n \"{{ $('Format Qualification Result').item.json.qualification.budget || '' }}\",\n \"{{ $('Format Qualification Result').item.json.qualification.timeline || '' }}\",\n \"{{ $('Format Qualification Result').item.json.score }}\",\n \"{{ $('Format Qualification Result').item.json.source }}\"\n ]\n ]\n}",
"options": {
"continueOnFail": true
}
},
"id": "b5d1e6f7-cf8f-8e5f-df6f-7f9a0b1c2d3e",
"name": "Save to Google Sheets",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
1050,
300
]
}
],
"connections": {
"Incoming Lead Webhook": {
"main": [
[
{
"node": "Parse Lead Message",
"type": "main",
"index": 0
}
]
]
},
"Parse Lead Message": {
"main": [
[
{
"node": "AI Qualify & Score Lead",
"type": "main",
"index": 0
}
]
]
},
"AI Qualify & Score Lead": {
"main": [
[
{
"node": "Format Qualification Result",
"type": "main",
"index": 0
}
]
]
},
"Format Qualification Result": {
"main": [
[
{
"node": "Save to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Save to Google Sheets": {
"main": []
}
},
"settings": {
"executionOrder": "v1"
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Lead Qualification AI — Multi-Niche Demo. Uses httpRequest. Webhook trigger; 5 nodes.
Source: https://github.com/DiyaHussein/deepseek-lead-bots/blob/main/lead-qualification-n8n-workflow.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow automates bulk email campaigns with built-in validation, deliverability protection, and smart send-time optimization.
Universal Lead Processing Workflow. Uses googleSheets, gmail, httpRequest, gmailTrigger. Webhook trigger; 34 nodes.
This workflow turns Feishu bot messages into a human-in-the-loop short-video production pipeline, using Tavily for web search, DeepSeek for topic and script generation, Jimeng AI for text-to-video, an
This workflow is designed to manage the assignment and validation of unique QR code coupons within a lead generation system with SuiteCRM.
This workflow acts as an instant SDR that replies to new inbound leads across multiple channels in real time. It first captures and normalizes all incoming lead data into a unified structure. The work