This workflow follows the Airtable → HTTP Request 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 →
{
"updatedAt": "2025-11-13T15:45:06.114Z",
"createdAt": "2025-11-13T14:47:47.438Z",
"id": "q1GEOHkLqlfUOuEe",
"name": "Buildnbloom - Typeform to Tier 1 Call",
"description": null,
"active": true,
"isArchived": false,
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "typeform-buildnbloom-leads",
"responseMode": "responseNode",
"options": {}
},
"id": "webhook-typeform",
"name": "Webhook - Typeform Lead",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
304
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={\"success\": true, \"message\": \"Lead received and processing\"}",
"options": {}
},
"id": "respond-webhook",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.2,
"position": [
464,
304
]
},
{
"parameters": {
"jsCode": "// Extract and clean lead data from Typeform webhook\nconst webhookData = $input.item.json;\n\n// Typeform sends data in 'form_response.answers' array\nconst answers = webhookData.form_response?.answers || [];\nconst fields = webhookData.form_response?.definition?.fields || [];\n\n// Helper function to find answer by field title\nfunction getAnswer(fieldTitle) {\n const field = fields.find(f => f.title.toLowerCase().includes(fieldTitle.toLowerCase()));\n if (!field) return null;\n \n const answer = answers.find(a => a.field.id === field.id);\n if (!answer) return null;\n \n // Handle different answer types\n if (answer.type === 'choice') return answer.choice?.label;\n if (answer.type === 'choices') return answer.choices?.labels.join(', ');\n if (answer.type === 'email') return answer.email;\n if (answer.type === 'phone_number') return answer.phone_number;\n if (answer.type === 'text') return answer.text;\n if (answer.type === 'number') return answer.number;\n \n return null;\n}\n\n// Extract fields\nconst name = getAnswer('name') || getAnswer('full name') || 'Unknown';\nconst email = getAnswer('email');\nconst rawPhone = getAnswer('phone') || getAnswer('mobile');\nconst serviceType = getAnswer('service') || getAnswer('service type');\nconst location = getAnswer('location') || getAnswer('suburb') || getAnswer('area');\nconst jobDetail = getAnswer('detail') || getAnswer('job') || getAnswer('description');\nconst timeline = getAnswer('timeline') || getAnswer('when') || getAnswer('urgency');\nconst budget = getAnswer('budget');\n\n// Clean phone number (ensure international format)\nlet cleanPhone = rawPhone;\nif (rawPhone) {\n // Remove all non-digit characters\n cleanPhone = rawPhone.replace(/\\D/g, '');\n \n // If starts with 0, replace with +61\n if (cleanPhone.startsWith('0')) {\n cleanPhone = '+61' + cleanPhone.substring(1);\n } else if (!cleanPhone.startsWith('+')) {\n // Assume Australian number\n cleanPhone = '+61' + cleanPhone;\n } else if (cleanPhone.startsWith('61')) {\n cleanPhone = '+' + cleanPhone;\n }\n}\n\nreturn {\n json: {\n name: name,\n email: email,\n phone: cleanPhone,\n service_type: serviceType,\n location: location,\n job_detail: jobDetail,\n timeline: timeline,\n budget: budget,\n source: 'Typeform',\n created_at: new Date().toISOString()\n }\n};"
},
"id": "extract-lead-data",
"name": "Extract Lead Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
688,
304
]
},
{
"parameters": {
"operation": "getAll",
"tableId": "leads",
"returnAll": true
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
912,
304
],
"id": "check-lead-exists",
"name": "Check if Lead Exists (Supabase)",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "lead-exists-check",
"leftValue": "={{ $input.all().length }}",
"rightValue": "1",
"operator": {
"type": "number",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "switch-new-existing",
"name": "Switch: New vs Existing Lead",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1120,
304
]
},
{
"parameters": {
"operation": "getAll",
"tableId": "leads",
"returnAll": true
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
1344,
192
],
"id": "fetch-existing-lead",
"name": "Fetch Existing Lead (Supabase)",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "update",
"tableId": "leads",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "name",
"fieldValue": "={{ $('Extract Lead Data').item.json.name }}"
},
{
"fieldId": "email",
"fieldValue": "={{ $('Extract Lead Data').item.json.email }}"
},
{
"fieldId": "service_type",
"fieldValue": "={{ $('Extract Lead Data').item.json.service_type }}"
},
{
"fieldId": "location",
"fieldValue": "={{ $('Extract Lead Data').item.json.location }}"
},
{
"fieldId": "job_detail",
"fieldValue": "={{ $('Extract Lead Data').item.json.job_detail }}"
},
{
"fieldId": "timeline",
"fieldValue": "={{ $('Extract Lead Data').item.json.timeline }}"
},
{
"fieldId": "budget",
"fieldValue": "={{ $('Extract Lead Data').item.json.budget }}"
}
]
}
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
1568,
192
],
"id": "update-existing-supabase",
"name": "Update Existing Lead (Supabase)",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "create",
"base": {
"__rl": true,
"value": "app6CWJXhP00mBfN6",
"mode": "list",
"cachedResultName": "Email Automation"
},
"table": {
"__rl": true,
"value": "tblOVOoTAn0GZ7JJ0",
"mode": "list",
"cachedResultName": "Leads"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"First Name": "={{ $('Extract Lead Data').item.json.name }}",
"Phone": "={{ $('Extract Lead Data').item.json.phone }}",
"Email Address": "={{ $('Extract Lead Data').item.json.email }}",
"Service Type": "={{ $('Extract Lead Data').item.json.service_type }}",
"Location": "={{ $('Extract Lead Data').item.json.location }}",
"Job Detail": "={{ $('Extract Lead Data').item.json.job_detail }}",
"Timeline": "={{ $('Extract Lead Data').item.json.timeline }}",
"Budget": "={{ $('Extract Lead Data').item.json.budget }}",
"Booking Status": "Not Booked",
"Call Status": "TBA",
"Contact status ": "Todo",
"Call Attempts": 0,
"SMS Count": 0,
"Email # Sent": 0,
"Captured Date": "={{ $now.toFormat('yyyy-MM-dd') }}"
},
"matchingColumns": [],
"schema": []
},
"options": {}
},
"id": "create-airtable-lead",
"name": "Create Airtable Lead",
"type": "n8n-nodes-base.airtable",
"typeVersion": 2,
"position": [
1344,
432
],
"credentials": {
"airtableTokenApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"tableId": "leads",
"fieldsUi": {
"fieldValues": [
{
"fieldValue": "={{ $('Extract Lead Data').item.json.phone }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.name }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.email }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.service_type }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.location }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.job_detail }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.timeline }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.budget }}"
},
{
"fieldValue": "={{ $('Create Airtable Lead').item.json.id }}"
},
{
"fieldValue": "false"
}
]
}
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
1568,
432
],
"id": "create-supabase-lead",
"name": "Create Supabase Lead",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"amount": 2,
"unit": "minutes"
},
"id": "wait-2min",
"name": "Wait 2min Before Call",
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
1792,
304
]
},
{
"parameters": {
"operation": "getAll",
"tableId": "messages",
"limit": 10
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2000,
192
],
"id": "fetch-sms-history",
"name": "Fetch SMS History (Supabase)",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "getAll",
"tableId": "calls",
"limit": 5
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2000,
304
],
"id": "fetch-call-history",
"name": "Fetch Call History (Supabase)",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "getAll",
"tableId": "leads",
"returnAll": true
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2000,
432
],
"id": "fetch-lead-summary",
"name": "Fetch Lead Summary (Supabase)",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Build comprehensive context for Retell AI\nconst leadData = $('Extract Lead Data').item.json;\nconst smsHistory = $('Fetch SMS History (Supabase)').first().json || [];\nconst callHistory = $('Fetch Call History (Supabase)').first().json || [];\nconst leadSummary = $('Fetch Lead Summary (Supabase)').first().json?.[0] || {};\n\nlet context = [];\n\n// Add AI summary if exists\nif (leadSummary.ai_summary) {\n context.push(`AI Summary: ${leadSummary.ai_summary}`);\n}\n\n// Add call history\nif (callHistory.length > 0) {\n const callSummaries = callHistory.map(c => \n `Call: ${c.status}, sentiment: ${c.sentiment || 'unknown'}, tier: ${c.call_tier || 'N/A'}`\n );\n context.push(`Call History: ${callSummaries.join(' | ')}`);\n}\n\n// Add SMS history\nif (smsHistory.length > 0) {\n const recentMsgs = smsHistory.slice(0, 10).map(m =>\n `[${m.direction === 'in' ? 'Lead' : 'AI'}]: ${m.content.substring(0, 100)}`\n );\n context.push(`SMS History: ${recentMsgs.join(' | ')}`);\n}\n\nconst fullContext = context.join(' || ') || 'First contact with lead';\n\nreturn {\n json: {\n lead_name: leadData.name,\n lead_phone: leadData.phone,\n lead_email: leadData.email,\n service_type: leadData.service_type || 'unspecified',\n location: leadData.location || 'unspecified',\n job_detail: leadData.job_detail || 'no details provided',\n timeline: leadData.timeline || 'not specified',\n budget: leadData.budget || 'not specified',\n conversation_history: fullContext,\n call_tier: 'Tier 1',\n call_attempts: leadSummary.call_attempts || 0,\n supabase_lead_id: leadSummary.id,\n airtable_lead_id: leadSummary.contact_id,\n agent_transfer_number: '{{YOUR_AU_PHONE_NUMBER}}'\n }\n};"
},
"id": "build-context",
"name": "Build Complete Context",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2224,
304
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.retellai.com/v2/create-phone-call",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"from_number\": \"{{YOUR_AU_PHONE_NUMBER}}\",\n \"to_number\": \"{{ $json.lead_phone }}\",\n \"agent_id\": \"agent_9dab470eb098b6b5b53ac2b95d\",\n \"metadata\": {\n \"supabase_lead_id\": \"{{ $json.supabase_lead_id }}\",\n \"airtable_lead_id\": \"{{ $json.airtable_lead_id }}\",\n \"lead_name\": \"{{ $json.lead_name }}\",\n \"service_type\": \"{{ $json.service_type }}\",\n \"location\": \"{{ $json.location }}\",\n \"call_tier\": \"Tier 1\",\n \"source\": \"Typeform\"\n },\n \"retell_llm_dynamic_variables\": {\n \"lead_name\": \"{{ $json.lead_name }}\",\n \"service_type\": \"{{ $json.service_type }}\",\n \"location\": \"{{ $json.location }}\",\n \"job_detail\": \"{{ $json.job_detail }}\",\n \"timeline\": \"{{ $json.timeline }}\",\n \"budget\": \"{{ $json.budget }}\",\n \"conversation_history\": \"{{ $json.conversation_history }}\",\n \"call_tier\": \"Tier 1\",\n \"agent_transfer_number\": \"{{ $json.agent_transfer_number }}\"\n }\n}",
"options": {}
},
"id": "tier1-retell-call",
"name": "Tier 1 - Retell Call",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2448,
304
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "update",
"base": {
"__rl": true,
"value": "app6CWJXhP00mBfN6",
"mode": "list",
"cachedResultName": "Email Automation"
},
"table": {
"__rl": true,
"value": "tblOVOoTAn0GZ7JJ0",
"mode": "list",
"cachedResultName": "Leads"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"id": "={{ $('Build Complete Context').item.json.airtable_lead_id }}",
"Call Status": "Call 1",
"Contact status ": "Called",
"Call Attempts": "={{ $('Build Complete Context').item.json.call_attempts + 1 }}",
"Last Call Date": "={{ $now.toFormat('yyyy-MM-dd HH:mm:ss') }}",
"Last Retell Call ID": "={{ $('Tier 1 - Retell Call').item.json.call_id }}"
},
"matchingColumns": [
"id"
],
"schema": []
},
"options": {}
},
"id": "update-airtable",
"name": "Update Airtable After Call",
"type": "n8n-nodes-base.airtable",
"typeVersion": 2,
"position": [
2672,
192
],
"credentials": {
"airtableTokenApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"tableId": "calls",
"fieldsUi": {
"fieldValues": [
{
"fieldValue": "={{ $('Build Complete Context').item.json.supabase_lead_id }}"
},
{
"fieldValue": "={{ $('Build Complete Context').item.json.lead_phone }}"
},
{
"fieldValue": "={{ $('Tier 1 - Retell Call').item.json.call_id }}"
},
{
"fieldValue": "initiated"
},
{
"fieldValue": "Tier 1"
}
]
}
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2672,
432
],
"id": "log-call-supabase",
"name": "Log Call to Supabase",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Webhook - Typeform Lead": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
},
{
"node": "Extract Lead Data",
"type": "main",
"index": 0
}
]
]
},
"Extract Lead Data": {
"main": [
[
{
"node": "Check if Lead Exists (Supabase)",
"type": "main",
"index": 0
}
]
]
},
"Check if Lead Exists (Supabase)": {
"main": [
[
{
"node": "Switch: New vs Existing Lead",
"type": "main",
"index": 0
}
]
]
},
"Switch: New vs Existing Lead": {
"main": [
[
{
"node": "Fetch Existing Lead (Supabase)",
"type": "main",
"index": 0
}
],
[
{
"node": "Create Airtable Lead",
"type": "main",
"index": 0
}
]
]
},
"Fetch Existing Lead (Supabase)": {
"main": [
[
{
"node": "Update Existing Lead (Supabase)",
"type": "main",
"index": 0
}
]
]
},
"Create Airtable Lead": {
"main": [
[
{
"node": "Create Supabase Lead",
"type": "main",
"index": 0
}
]
]
},
"Update Existing Lead (Supabase)": {
"main": [
[
{
"node": "Wait 2min Before Call",
"type": "main",
"index": 0
}
]
]
},
"Create Supabase Lead": {
"main": [
[
{
"node": "Wait 2min Before Call",
"type": "main",
"index": 0
}
]
]
},
"Wait 2min Before Call": {
"main": [
[
{
"node": "Fetch SMS History (Supabase)",
"type": "main",
"index": 0
},
{
"node": "Fetch Call History (Supabase)",
"type": "main",
"index": 0
},
{
"node": "Fetch Lead Summary (Supabase)",
"type": "main",
"index": 0
}
]
]
},
"Fetch SMS History (Supabase)": {
"main": [
[
{
"node": "Build Complete Context",
"type": "main",
"index": 0
}
]
]
},
"Fetch Call History (Supabase)": {
"main": [
[
{
"node": "Build Complete Context",
"type": "main",
"index": 0
}
]
]
},
"Fetch Lead Summary (Supabase)": {
"main": [
[
{
"node": "Build Complete Context",
"type": "main",
"index": 0
}
]
]
},
"Build Complete Context": {
"main": [
[
{
"node": "Tier 1 - Retell Call",
"type": "main",
"index": 0
}
]
]
},
"Tier 1 - Retell Call": {
"main": [
[
{
"node": "Update Airtable After Call",
"type": "main",
"index": 0
},
{
"node": "Log Call to Supabase",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"meta": null,
"versionId": "{{YOUR_NOTION_PAGE_ID}}",
"activeVersionId": "{{YOUR_NOTION_PAGE_ID}}",
"versionCounter": 14,
"triggerCount": 1,
"shared": [
{
"updatedAt": "2025-11-13T14:47:47.438Z",
"createdAt": "2025-11-13T14:47:47.438Z",
"role": "workflow:owner",
"workflowId": "q1GEOHkLqlfUOuEe",
"projectId": "7NOiDJlVGtj6HHEb",
"project": {
"updatedAt": "2025-01-26T16:28:33.630Z",
"createdAt": "2025-01-26T11:37:02.698Z",
"id": "7NOiDJlVGtj6HHEb",
"name": "Rayan Ratego <rayanratego@gmail.com>",
"type": "personal",
"icon": null,
"description": null,
"creatorId": "{{YOUR_NOTION_PAGE_ID}}",
"projectRelations": [
{
"updatedAt": "2025-01-26T11:37:02.698Z",
"createdAt": "2025-01-26T11:37:02.698Z",
"userId": "{{YOUR_NOTION_PAGE_ID}}",
"projectId": "7NOiDJlVGtj6HHEb",
"user": {
"updatedAt": "2026-05-06T14:08:54.748Z",
"createdAt": "2025-01-26T11:36:47.660Z",
"id": "{{YOUR_NOTION_PAGE_ID}}",
"email": "rayanratego@gmail.com",
"firstName": "Rayan",
"lastName": "Ratego",
"personalizationAnswers": {
"version": "v4",
"personalization_survey_submitted_at": "2025-01-26T16:29:57.338Z",
"personalization_survey_n8n_version": "1.75.2",
"companyIndustryExtended": [
"it-industry",
"healthcare",
"marketing-industry",
"media-industry"
],
"companySize": "<20",
"companyType": "other",
"role": "business-owner",
"reportedSource": "youtube"
},
"settings": {
"userActivated": true,
"easyAIWorkflowOnboarded": true,
"firstSuccessfulWorkflowId": "qyOU7EgejsL50BFL",
"userActivatedAt": 1757343922037,
"npsSurvey": {
"responded": true,
"lastShownAt": 1771221135008
}
},
"disabled": false,
"mfaEnabled": false,
"lastActiveAt": "2026-05-06",
"isPending": false
}
}
]
}
}
],
"tags": [],
"activeVersion": {
"updatedAt": "2026-01-08T06:31:31.798Z",
"createdAt": "2026-01-08T06:31:31.798Z",
"versionId": "{{YOUR_NOTION_PAGE_ID}}",
"workflowId": "q1GEOHkLqlfUOuEe",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "typeform-buildnbloom-leads",
"responseMode": "responseNode",
"options": {}
},
"id": "webhook-typeform",
"name": "Webhook - Typeform Lead",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
304
],
"webhookId": "typeform-buildnbloom-leads"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={\"success\": true, \"message\": \"Lead received and processing\"}",
"options": {}
},
"id": "respond-webhook",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.2,
"position": [
464,
304
]
},
{
"parameters": {
"jsCode": "// Extract and clean lead data from Typeform webhook\nconst webhookData = $input.item.json;\n\n// Typeform sends data in 'form_response.answers' array\nconst answers = webhookData.form_response?.answers || [];\nconst fields = webhookData.form_response?.definition?.fields || [];\n\n// Helper function to find answer by field title\nfunction getAnswer(fieldTitle) {\n const field = fields.find(f => f.title.toLowerCase().includes(fieldTitle.toLowerCase()));\n if (!field) return null;\n \n const answer = answers.find(a => a.field.id === field.id);\n if (!answer) return null;\n \n // Handle different answer types\n if (answer.type === 'choice') return answer.choice?.label;\n if (answer.type === 'choices') return answer.choices?.labels.join(', ');\n if (answer.type === 'email') return answer.email;\n if (answer.type === 'phone_number') return answer.phone_number;\n if (answer.type === 'text') return answer.text;\n if (answer.type === 'number') return answer.number;\n \n return null;\n}\n\n// Extract fields\nconst name = getAnswer('name') || getAnswer('full name') || 'Unknown';\nconst email = getAnswer('email');\nconst rawPhone = getAnswer('phone') || getAnswer('mobile');\nconst serviceType = getAnswer('service') || getAnswer('service type');\nconst location = getAnswer('location') || getAnswer('suburb') || getAnswer('area');\nconst jobDetail = getAnswer('detail') || getAnswer('job') || getAnswer('description');\nconst timeline = getAnswer('timeline') || getAnswer('when') || getAnswer('urgency');\nconst budget = getAnswer('budget');\n\n// Clean phone number (ensure international format)\nlet cleanPhone = rawPhone;\nif (rawPhone) {\n // Remove all non-digit characters\n cleanPhone = rawPhone.replace(/\\D/g, '');\n \n // If starts with 0, replace with +61\n if (cleanPhone.startsWith('0')) {\n cleanPhone = '+61' + cleanPhone.substring(1);\n } else if (!cleanPhone.startsWith('+')) {\n // Assume Australian number\n cleanPhone = '+61' + cleanPhone;\n } else if (cleanPhone.startsWith('61')) {\n cleanPhone = '+' + cleanPhone;\n }\n}\n\nreturn {\n json: {\n name: name,\n email: email,\n phone: cleanPhone,\n service_type: serviceType,\n location: location,\n job_detail: jobDetail,\n timeline: timeline,\n budget: budget,\n source: 'Typeform',\n created_at: new Date().toISOString()\n }\n};"
},
"id": "extract-lead-data",
"name": "Extract Lead Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
688,
304
]
},
{
"parameters": {
"operation": "getAll",
"tableId": "leads",
"returnAll": true
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
912,
304
],
"id": "check-lead-exists",
"name": "Check if Lead Exists (Supabase)",
"credentials": {
"supabaseApi": {
"id": "lRWuQG3VAWEX5LNi",
"name": "BNB"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "lead-exists-check",
"leftValue": "={{ $input.all().length }}",
"rightValue": "1",
"operator": {
"type": "number",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "switch-new-existing",
"name": "Switch: New vs Existing Lead",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1120,
304
]
},
{
"parameters": {
"operation": "getAll",
"tableId": "leads",
"returnAll": true
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
1344,
192
],
"id": "fetch-existing-lead",
"name": "Fetch Existing Lead (Supabase)",
"credentials": {
"supabaseApi": {
"id": "lRWuQG3VAWEX5LNi",
"name": "BNB"
}
}
},
{
"parameters": {
"operation": "update",
"tableId": "leads",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "name",
"fieldValue": "={{ $('Extract Lead Data').item.json.name }}"
},
{
"fieldId": "email",
"fieldValue": "={{ $('Extract Lead Data').item.json.email }}"
},
{
"fieldId": "service_type",
"fieldValue": "={{ $('Extract Lead Data').item.json.service_type }}"
},
{
"fieldId": "location",
"fieldValue": "={{ $('Extract Lead Data').item.json.location }}"
},
{
"fieldId": "job_detail",
"fieldValue": "={{ $('Extract Lead Data').item.json.job_detail }}"
},
{
"fieldId": "timeline",
"fieldValue": "={{ $('Extract Lead Data').item.json.timeline }}"
},
{
"fieldId": "budget",
"fieldValue": "={{ $('Extract Lead Data').item.json.budget }}"
}
]
}
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
1568,
192
],
"id": "update-existing-supabase",
"name": "Update Existing Lead (Supabase)",
"credentials": {
"supabaseApi": {
"id": "lRWuQG3VAWEX5LNi",
"name": "BNB"
}
}
},
{
"parameters": {
"operation": "create",
"base": {
"__rl": true,
"value": "app6CWJXhP00mBfN6",
"mode": "list",
"cachedResultName": "Email Automation"
},
"table": {
"__rl": true,
"value": "tblOVOoTAn0GZ7JJ0",
"mode": "list",
"cachedResultName": "Leads"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"First Name": "={{ $('Extract Lead Data').item.json.name }}",
"Phone": "={{ $('Extract Lead Data').item.json.phone }}",
"Email Address": "={{ $('Extract Lead Data').item.json.email }}",
"Service Type": "={{ $('Extract Lead Data').item.json.service_type }}",
"Location": "={{ $('Extract Lead Data').item.json.location }}",
"Job Detail": "={{ $('Extract Lead Data').item.json.job_detail }}",
"Timeline": "={{ $('Extract Lead Data').item.json.timeline }}",
"Budget": "={{ $('Extract Lead Data').item.json.budget }}",
"Booking Status": "Not Booked",
"Call Status": "TBA",
"Contact status ": "Todo",
"Call Attempts": 0,
"SMS Count": 0,
"Email # Sent": 0,
"Captured Date": "={{ $now.toFormat('yyyy-MM-dd') }}"
},
"matchingColumns": [],
"schema": []
},
"options": {}
},
"id": "create-airtable-lead",
"name": "Create Airtable Lead",
"type": "n8n-nodes-base.airtable",
"typeVersion": 2,
"position": [
1344,
432
],
"credentials": {
"airtableTokenApi": {
"id": "airtable-buildnbloom",
"name": "Airtable Buildnbloom"
}
}
},
{
"parameters": {
"tableId": "leads",
"fieldsUi": {
"fieldValues": [
{
"fieldValue": "={{ $('Extract Lead Data').item.json.phone }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.name }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.email }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.service_type }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.location }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.job_detail }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.timeline }}"
},
{
"fieldValue": "={{ $('Extract Lead Data').item.json.budget }}"
},
{
"fieldValue": "={{ $('Create Airtable Lead').item.json.id }}"
},
{
"fieldValue": "false"
}
]
}
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
1568,
432
],
"id": "create-supabase-lead",
"name": "Create Supabase Lead",
"credentials": {
"supabaseApi": {
"id": "lRWuQG3VAWEX5LNi",
"name": "BNB"
}
}
},
{
"parameters": {
"amount": 2,
"unit": "minutes"
},
"id": "wait-2min",
"name": "Wait 2min Before Call",
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
1792,
304
],
"webhookId": "wait-2min-buildnbloom"
},
{
"parameters": {
"operation": "getAll",
"tableId": "messages",
"limit": 10
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2000,
192
],
"id": "fetch-sms-history",
"name": "Fetch SMS History (Supabase)",
"credentials": {
"supabaseApi": {
"id": "lRWuQG3VAWEX5LNi",
"name": "BNB"
}
}
},
{
"parameters": {
"operation": "getAll",
"tableId": "calls",
"limit": 5
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2000,
304
],
"id": "fetch-call-history",
"name": "Fetch Call History (Supabase)",
"credentials": {
"supabaseApi": {
"id": "lRWuQG3VAWEX5LNi",
"name": "BNB"
}
}
},
{
"parameters": {
"operation": "getAll",
"tableId": "leads",
"returnAll": true
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2000,
432
],
"id": "fetch-lead-summary",
"name": "Fetch Lead Summary (Supabase)",
"credentials": {
"supabaseApi": {
"id": "lRWuQG3VAWEX5LNi",
"name": "BNB"
}
}
},
{
"parameters": {
"jsCode": "// Build comprehensive context for Retell AI\nconst leadData = $('Extract Lead Data').item.json;\nconst smsHistory = $('Fetch SMS History (Supabase)').first().json || [];\nconst callHistory = $('Fetch Call History (Supabase)').first().json || [];\nconst leadSummary = $('Fetch Lead Summary (Supabase)').first().json?.[0] || {};\n\nlet context = [];\n\n// Add AI summary if exists\nif (leadSummary.ai_summary) {\n context.push(`AI Summary: ${leadSummary.ai_summary}`);\n}\n\n// Add call history\nif (callHistory.length > 0) {\n const callSummaries = callHistory.map(c => \n `Call: ${c.status}, sentiment: ${c.sentiment || 'unknown'}, tier: ${c.call_tier || 'N/A'}`\n );\n context.push(`Call History: ${callSummaries.join(' | ')}`);\n}\n\n// Add SMS history\nif (smsHistory.length > 0) {\n const recentMsgs = smsHistory.slice(0, 10).map(m =>\n `[${m.direction === 'in' ? 'Lead' : 'AI'}]: ${m.content.substring(0, 100)}`\n );\n context.push(`SMS History: ${recentMsgs.join(' | ')}`);\n}\n\nconst fullContext = context.join(' || ') || 'First contact with lead';\n\nreturn {\n json: {\n lead_name: leadData.name,\n lead_phone: leadData.phone,\n lead_email: leadData.email,\n service_type: leadData.service_type || 'unspecified',\n location: leadData.location || 'unspecified',\n job_detail: leadData.job_detail || 'no details provided',\n timeline: leadData.timeline || 'not specified',\n budget: leadData.budget || 'not specified',\n conversation_history: fullContext,\n call_tier: 'Tier 1',\n call_attempts: leadSummary.call_attempts || 0,\n supabase_lead_id: leadSummary.id,\n airtable_lead_id: leadSummary.contact_id,\n agent_transfer_number: '{{YOUR_AU_PHONE_NUMBER}}'\n }\n};"
},
"id": "build-context",
"name": "Build Complete Context",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2224,
304
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.retellai.com/v2/create-phone-call",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"from_number\": \"{{YOUR_AU_PHONE_NUMBER}}\",\n \"to_number\": \"{{ $json.lead_phone }}\",\n \"agent_id\": \"agent_9dab470eb098b6b5b53ac2b95d\",\n \"metadata\": {\n \"supabase_lead_id\": \"{{ $json.supabase_lead_id }}\",\n \"airtable_lead_id\": \"{{ $json.airtable_lead_id }}\",\n \"lead_name\": \"{{ $json.lead_name }}\",\n \"service_type\": \"{{ $json.service_type }}\",\n \"location\": \"{{ $json.location }}\",\n \"call_tier\": \"Tier 1\",\n \"source\": \"Typeform\"\n },\n \"retell_llm_dynamic_variables\": {\n \"lead_name\": \"{{ $json.lead_name }}\",\n \"service_type\": \"{{ $json.service_type }}\",\n \"location\": \"{{ $json.location }}\",\n \"job_detail\": \"{{ $json.job_detail }}\",\n \"timeline\": \"{{ $json.timeline }}\",\n \"budget\": \"{{ $json.budget }}\",\n \"conversation_history\": \"{{ $json.conversation_history }}\",\n \"call_tier\": \"Tier 1\",\n \"agent_transfer_number\": \"{{ $json.agent_transfer_number }}\"\n }\n}",
"options": {}
},
"id": "tier1-retell-call",
"name": "Tier 1 - Retell Call",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2448,
304
],
"credentials": {
"httpHeaderAuth": {
"id": "Cymy0OG4707gG3br",
"name": "webhook eleven"
}
}
},
{
"parameters": {
"operation": "update",
"base": {
"__rl": true,
"value": "app6CWJXhP00mBfN6",
"mode": "list",
"cachedResultName": "Email Automation"
},
"table": {
"__rl": true,
"value": "tblOVOoTAn0GZ7JJ0",
"mode": "list",
"cachedResultName": "Leads"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"id": "={{ $('Build Complete Context').item.json.airtable_lead_id }}",
"Call Status": "Call 1",
"Contact status ": "Called",
"Call Attempts": "={{ $('Build Complete Context').item.json.call_attempts + 1 }}",
"Last Call Date": "={{ $now.toFormat('yyyy-MM-dd HH:mm:ss') }}",
"Last Retell Call ID": "={{ $('Tier 1 - Retell Call').item.json.call_id }}"
},
"matchingColumns": [
"id"
],
"schema": []
},
"options": {}
},
"id": "update-airtable",
"name": "Update Airtable After Call",
"type": "n8n-nodes-base.airtable",
"typeVersion": 2,
"position": [
2672,
192
],
"credentials": {
"airtableTokenApi": {
"id": "airtable-buildnbloom",
"name": "Airtable Buildnbloom"
}
}
},
{
"parameters": {
"tableId": "calls",
"fieldsUi": {
"fieldValues": [
{
"fieldValue": "={{ $('Build Complete Context').item.json.supabase_lead_id }}"
},
{
"fieldValue": "={{ $('Build Complete Context').item.json.lead_phone }}"
},
{
"fieldValue": "={{ $('Tier 1 - Retell Call').item.json.call_id }}"
},
{
"fieldValue": "initiated"
},
{
"fieldValue": "Tier 1"
}
]
}
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2672,
432
],
"id": "log-call-supabase",
"name": "Log Call to Supabase",
"credentials": {
"supabaseApi": {
"id": "lRWuQG3VAWEX5LNi",
"name": "BNB"
}
}
}
],
"connections": {
"Webhook - Typeform Lead": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
},
{
"node": "Extract Lead Data",
"type": "main",
"index": 0
}
]
]
},
"Extract Lead Data": {
"main": [
[
{
"node": "Check if Lead Exists (Supabase)",
"type": "main",
"index": 0
}
]
]
},
"Check if Lead Exists (Supabase)": {
"main": [
[
{
"node": "Switch: New vs Existing Lead",
"type": "main",
"index": 0
}
]
]
},
"Switch: New vs Existing Lead": {
"main": [
[
{
"node": "Fetch Existing Lead (Supabase)",
"type": "main",
"index": 0
}
],
[
{
"node": "Create Airtable Lead",
"type": "main",
"index": 0
}
]
]
},
"Fetch Existing Lead (Supabase)": {
"main": [
[
{
"node": "Update Existing Lead (Supabase)",
"type": "main",
"index": 0
}
]
]
},
"Create Airtable Lead": {
"main": [
[
{
"node": "Create Supabase Lead",
"type": "main",
"index": 0
}
]
]
},
"Update Existing Lead (Supabase)": {
"main": [
[
{
"node": "Wait 2min Before Call",
"type": "main",
"index": 0
}
]
]
},
"Create Supabase Lead": {
"main": [
[
{
"node": "Wait 2min Before Call",
"type": "main",
"index": 0
}
]
]
},
"Wait 2min Before Call": {
"main": [
[
{
"node": "Fetch SMS History (Supabase)",
"type": "main",
"index": 0
},
{
"node": "Fetch Call History (Supabase)",
"type": "main",
"index": 0
},
{
"node": "Fetch Lead Summary (Supabase)",
"type": "main",
"index": 0
}
]
]
},
"Fetch SMS History (Supabase)": {
"main": [
[
{
"node": "Build Complete Context",
"type": "main",
"index": 0
}
]
]
},
"Fetch Call History (Supabase)": {
"main": [
[
{
"node": "Build Complete Context",
"type": "main",
"index": 0
}
]
]
},
"Fetch Lead Summary (Supabase)": {
"main": [
[
{
"node": "Build Complete Context",
"type": "main",
"index": 0
}
]
]
},
"Build Complete Context": {
"main": [
[
{
"node": "Tier 1 - Retell Call",
"type": "main",
"index": 0
}
]
]
},
"Tier 1 - Retell Call": {
"main": [
[
{
"node": "Update Airtable After Call",
"type": "main",
"index": 0
},
{
"node": "Log Call to Supabase",
"type": "main",
"index": 0
}
]
]
}
},
"authors": "system migration",
"name": null,
"description": null,
"autosaved": false,
"workflowPublishHistory": [
{
"createdAt": "2025-11-13T15:45:06.114Z",
"id": 46,
"workflowId": "q1GEOHkLqlfUOuEe",
"versionId": "{{YOUR_NOTION_PAGE_ID}}",
"event": "activated",
"userId": null
}
]
}
}
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.
airtableTokenApihttpHeaderAuthsupabaseApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Buildnbloom - Typeform to Tier 1 Call. Uses supabase, airtable, httpRequest. Webhook trigger; 17 nodes.
Source: https://gist.github.com/Iaminfitite/b6a40dab75a7ff98420dbb69a7f6518d — 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.
2. Refresh Pipedrive tokens. Uses stopAndError, stickyNote, supabase, httpRequest. Webhook trigger; 29 nodes.
This workflow provides an OAuth 2.0 auth token refresh process for better control. Developers can utilize it as an alternative to n8n's built-in OAuth flow to achieve improved control and visibility.
Ai Assistant Workflow. Uses supabase, httpRequest, emailSend. Webhook trigger; 14 nodes.
Automação Master: Pedidos & Reservas (Web & App) - Evolution MultiTenant. Uses httpRequest, supabase. Webhook trigger; 14 nodes.
Barbearia SaaS Pro. Uses supabase, httpRequest, chatwoot. Webhook trigger; 10 nodes.