AutomationFlowsData & Sheets › Buildnbloom - Typeform to Tier 1 Call

Buildnbloom - Typeform to Tier 1 Call

Buildnbloom - Typeform to Tier 1 Call. Uses supabase, airtable, httpRequest. Webhook trigger; 17 nodes.

Webhook trigger★★★★☆ complexity17 nodesSupabaseAirtableHTTP Request
Data & Sheets Trigger: Webhook Nodes: 17 Complexity: ★★★★☆ Added:

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 →

Download .json
{
  "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.

Pro

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 →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

2. Refresh Pipedrive tokens. Uses stopAndError, stickyNote, supabase, httpRequest. Webhook trigger; 29 nodes.

Stop And Error, Supabase, HTTP Request
Data & Sheets

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.

Stop And Error, Supabase, HTTP Request
Data & Sheets

Ai Assistant Workflow. Uses supabase, httpRequest, emailSend. Webhook trigger; 14 nodes.

Supabase, HTTP Request, Email Send
Data & Sheets

Automação Master: Pedidos & Reservas (Web & App) - Evolution MultiTenant. Uses httpRequest, supabase. Webhook trigger; 14 nodes.

HTTP Request, Supabase
Data & Sheets

Barbearia SaaS Pro. Uses supabase, httpRequest, chatwoot. Webhook trigger; 10 nodes.

Supabase, HTTP Request, Chatwoot