This workflow follows the HTTP Request → OpenAI 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 →
{
"name": "Phase 6 - Lead Scoring",
"nodes": [
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "768a0599-beed-4bfc-b940-b267bb1bba8f",
"name": "supabaseUrl",
"value": "https://YOUR_PROJECT_REF.supabase.co",
"type": "string"
}
]
},
"options": {}
},
"id": "7e204228-95a4-444d-b85f-1d9e6e1736ba",
"name": "Config",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
816,
2592
]
},
{
"parameters": {
"method": "PATCH",
"url": "={{ $('Config').item.json.supabaseUrl + '/rest/v1/contacts?id=eq.' + $json.contactId }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "supabaseApi",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Prefer",
"value": "return=minimal"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ { \"lead_band\": $json.lead_band, \"lead_score\": $json.lead_score, \"lead_reasoning\": $json.lead_reasoning } }}",
"options": {}
},
"id": "b49f393e-dea9-4405-a448-51de44030bca",
"name": "Write Score to Contact",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2208,
2592
],
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2000,
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"url": "={{ $('Config').item.json.supabaseUrl + '/rest/v1/meetings?meeting_notes=not.is.null&select=id,meeting_notes,contact_id,contacts(name,role,school_id,schools(name,tier,board))' }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "supabaseApi",
"options": {}
},
"id": "1eb3c973-9b4d-40b7-b256-35c2e73999ae",
"name": "Get Meetings w/ Notes",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1040,
2592
],
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2000,
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"modelId": {
"__rl": true,
"value": "gpt-4o-mini",
"mode": "list",
"cachedResultName": "GPT-4O-MINI"
},
"responses": {
"values": [
{
"role": "system",
"content": "You are a lead-scoring assistant for Learn with Leaders. Read the meeting notes and score the lead's readiness to partner.\n\nSignals \u2014 Positive: explicit interest or a concrete next step named; a decision-maker is involved; timeline urgency; strong program fit or large student numbers. Negative: unresolved objections; \"just exploring\"; went quiet or non-committal; poor fit.\n\nBands: hot = ready to move + decision-maker + clear next step; warm = genuinely interested but has blockers (budget, sign-off, timing); cold = low interest or poor fit. Also give a 0-100 score (hot ~70-100, warm ~40-69, cold ~0-39).\n\nReturn ONLY strict JSON \u2014 no markdown, no code fences, no extra text:\n{\"band\":\"hot|warm|cold\",\"score\":<integer>,\"reasoning\":\"<1-2 sentences citing the notes>\"}"
},
{
"content": "={{ $json.userPrompt }}"
}
]
},
"builtInTools": {},
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 2.3,
"position": [
1520,
2592
],
"id": "a2423c56-9139-4057-98a9-ee88fdd54d72",
"name": "Message a model",
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
576,
2592
],
"id": "347f5584-a152-4d7b-b6af-67cc2ce56f07",
"name": "When clicking \u2018Execute workflow\u2019"
},
{
"parameters": {
"jsCode": "const src = $('Build Scoring').all();\nfunction extractText(r) {\n if (r == null) return '';\n if (typeof r === 'string') return r;\n if (Array.isArray(r.output)) {\n let acc = '';\n for (const msg of r.output) {\n if (msg && Array.isArray(msg.content)) {\n for (const c of msg.content) { if (c && typeof c.text === 'string') acc += c.text; }\n } else if (typeof msg === 'string') { acc += msg; }\n else if (msg && typeof msg.text === 'string') { acc += msg.text; }\n }\n if (acc) return acc;\n }\n if (typeof r.output_text === 'string') return r.output_text;\n if (typeof r.output === 'string') return r.output;\n if (typeof r.content === 'string') return r.content;\n if (typeof r.text === 'string') return r.text;\n if (r.message && typeof r.message.content === 'string') return r.message.content;\n if (r.choices && r.choices[0] && r.choices[0].message && typeof r.choices[0].message.content === 'string') return r.choices[0].message.content;\n if (Array.isArray(r.content)) return r.content.map(b => (b && b.text) ? b.text : '').join('');\n return '';\n}\nconst out = [];\nfor (let i = 0; i < items.length; i++) {\n let t = extractText(items[i].json).trim();\n t = t.replace(/```json/gi, '').replace(/```/g, '').trim();\n const m = t.match(/\\{[\\s\\S]*\\}/);\n let obj = {};\n try { obj = JSON.parse(m ? m[0] : t); } catch (e) { obj = {}; }\n const band = (obj.band || '').toString().toLowerCase();\n const validBand = ['cold','warm','hot'].includes(band) ? band : null;\n const c = (src[i] && src[i].json) ? src[i].json : {};\n if (!validBand || !c.contactId) continue;\n const score = Number(obj.score);\n out.push({ json: {\n contactId: c.contactId,\n lead_band: validBand,\n lead_score: Number.isFinite(score) ? Math.round(score) : null,\n lead_reasoning: (obj.reasoning || '').toString()\n }});\n}\nreturn out;\n"
},
"id": "81ab8722-6775-425b-afa2-2a8391f716f8",
"name": "Extract Score",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1968,
2592
]
},
{
"parameters": {
"jsCode": "const out = [];\nfor (const item of items) {\n const m = item.json;\n const c = Array.isArray(m.contacts) ? (m.contacts[0]||{}) : (m.contacts||{});\n const s = c && (Array.isArray(c.schools) ? (c.schools[0]||{}) : (c.schools||{})) || {};\n const userPrompt =\n \"Score this lead from the meeting notes.\\n\" +\n \"Contact: \" + (c.name || 'Unknown') + \" (\" + (c.role || 'school contact') + \") at \" + (s.name || 'their school') +\n (s.tier != null ? \" [Tier \" + s.tier + \"]\" : \"\") + \".\\n\\n\" +\n \"MEETING NOTES:\\n\" + (m.meeting_notes || '(no notes)') + \"\\n\";\n out.push({ json: { contactId: m.contact_id, userPrompt: userPrompt } });\n}\nreturn out;\n"
},
"id": "66441dd2-e59a-4765-ab22-03266f46639c",
"name": "Build Scoring",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1264,
2592
]
}
],
"connections": {
"When clicking \u2018Execute workflow\u2019": {
"main": [
[
{
"node": "Config",
"type": "main",
"index": 0
}
]
]
},
"Get Meetings w/ Notes": {
"main": [
[
{
"node": "Build Scoring",
"type": "main",
"index": 0
}
]
]
},
"Build Scoring": {
"main": [
[
{
"node": "Message a model",
"type": "main",
"index": 0
}
]
]
},
"Extract Score": {
"main": [
[
{
"node": "Write Score to Contact",
"type": "main",
"index": 0
}
]
]
},
"Config": {
"main": [
[
{
"node": "Get Meetings w/ Notes",
"type": "main",
"index": 0
}
]
]
},
"Message a model": {
"main": [
[
{
"node": "Extract Score",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
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.
openAiApisupabaseApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Phase 6 - Lead Scoring. Uses httpRequest, openAi. Event-driven trigger; 7 nodes.
Source: https://github.com/Tusharvijaypatil/LWL-Growth-Engine/blob/main/Workflows/phase7_lead_scoring.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.
Ask questions like “How much did I spend on food last month?” and get instant answers from your financial data — directly in Telegram.
Analyze incoming support requests, classify intent and priority with AI, create Jira tickets, assign the correct team, send Slack notifications, and track SLA deadlines. Supports Gmail, WhatsApp, form
The Problem That it Solves
This intelligent email automation workflow helps you maximize engagement through domain-based outreach. It utilizes AI-powered personalization and strategic follow-ups to increase response rates. The
Note: Now includes an Apify alternative for Rapid API (Some users can't create new accounts on Rapid API, so I have added an alternative for you. But immediately you are able to get access to Rapid AP