{
  "id": "CbpLxcAwS2HCvdAG",
  "name": "Run AI voice outreach from Airtable with Bolna, Groq, Brevo and AiSensy",
  "tags": [
    {
      "id": "BQoUk1cQ6taXZTMT",
      "name": "JobRaahi",
      "createdAt": "2026-07-10T18:56:30.295Z",
      "updatedAt": "2026-07-10T18:56:30.295Z"
    }
  ],
  "nodes": [
    {
      "id": "6ab5a245-b615-4055-b9bf-a6cc9a87e65c",
      "name": "Airtable \u2014 Get Contacts",
      "type": "n8n-nodes-base.airtable",
      "notes": "Picks up: (1) fresh records where Call Status is empty, AND (2) records marked No Answer - 1 that were last called 3+ days ago. Skips records with no phone number.",
      "position": [
        -1840,
        608
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_AIRTABLE_BASE_ID"
        },
        "table": {
          "__rl": true,
          "mode": "name",
          "value": "YOUR_AIRTABLE_TABLE_ID"
        },
        "options": {},
        "operation": "search",
        "filterByFormula": "NOT({Coordinator Phone} = '')"
      },
      "typeVersion": 2
    },
    {
      "id": "e6995f6a-e73c-499d-9798-fbdb149da111",
      "name": "Loop Over Colleges",
      "type": "n8n-nodes-base.splitInBatches",
      "notes": "Processes one college at a time. Output [0] = current item. Output [1] = done signal (not connected \u2014 workflow ends cleanly when all records are processed).",
      "position": [
        -1584,
        608
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "8658ae76-6168-4d28-b486-b7395685c76f",
      "name": "Bolna.ai \u2014 Place Call",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Places outbound call via Bolna.ai to the coordinator's phone. PHONE FORMAT: Airtable must store numbers in international format e.g. +919876543210. Bolna returns a call_id used in the next step. Agent ID is already set.",
      "position": [
        -1040,
        608
      ],
      "parameters": {
        "url": "https://api.bolna.dev/call",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n\"agent_id\": \"9d84fe84-f6ac-487f-a4a4-8b23604d5286\",\n\"recipient_phone_number\": \"{{ $json['Coordinator Phone'] }}\",\n  \"user_data\": {\n    \"name\": \"{{ $json['Coordinator Name'] }}\",\n    \"college\": \"{{ $json['College Name'] }}\"\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "3f5bffb8-1865-44de-9b36-4e5e17ae47ee",
      "name": "Bolna \u2014 Get Call Status",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Fetches full call data from Bolna. Key fields used downstream: conversation_duration (to detect pickup) and transcript (for Claude analysis). IF THIS FAILS: Bolna might return 'id' instead of 'call_id' in the POST response \u2014 open this node and change call_id to id in the URL.",
      "position": [
        -656,
        608
      ],
      "parameters": {
        "url": "=https://api.bolna.dev/agent/YOUR_BOLNA_AGENT_ID/execution/{{ $('Bolna.ai \u2014 Place Call').item.json.execution_id }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "8dfbd56b-769f-4c65-a9bc-956a2571e13b",
      "name": "IF \u2014 Did They Pick Up?",
      "type": "n8n-nodes-base.if",
      "notes": "TRUE [0] = conversation_duration > 0 meaning someone spoke. FALSE [1] = null or 0 duration meaning no answer or busy. Number() safely converts null to 0.",
      "position": [
        -416,
        608
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond-picked-up",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ !!$json.transcript }}",
              "rightValue": {}
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "b186aea3-2e1d-408e-84bf-b95dcd0067c0",
      "name": "IF \u2014 Interested?",
      "type": "n8n-nodes-base.if",
      "notes": "TRUE [0] = Claude said YES (coordinator is interested). FALSE [1] = Claude said NO. caseSensitive is false so YES / yes / Yes all match.",
      "position": [
        96,
        416
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond-interested",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.choices[0].message.content }}",
              "rightValue": "Interested"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "f39c1791-0e92-4a82-920f-36b57f3f377c",
      "name": "Brevo \u2014 Opportunity Email",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "ACTION REQUIRED: Replace PASTE_YOUR_BREVO_API_KEY_HERE with your actual Brevo API key. Find it at: Brevo dashboard \u2192 Settings \u2192 SMTP and API \u2192 API Keys. It starts with xkeysib-",
      "position": [
        272,
        208
      ],
      "parameters": {
        "url": "https://api.brevo.com/v3/smtp/email",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"sender\": {\n    \"name\": \"JobRaahi Team\",\n    \"email\": \"YOUR_SENDER_EMAIL@example.com\"\n  },\n  \"to\": [\n    {\n      \"email\": \"{{ $('Loop Over Colleges').item.json['Coordinator Email'] }}\",\n      \"name\": \"{{ $('Loop Over Colleges').item.json['Coordinator Name'] }}\"\n    }\n  ],\n  \"subject\": \"Thank You for Connecting with Job Raahi \u2014 Next Steps Enclosed\",\n  \"htmlContent\": \"<p>Dear Sir/Madam,</p><p>Hope you are doing well.</p><p>It was great speaking with you today! I am Gargi from Job Raahi \u2014 a free digital job portal specifically designed for ITI, Polytechnic, and entry-level candidates across India.</p><p>As discussed on the call, Job Raahi helps students from institutions like yours directly connect with verified employers \u2014 at no cost whatsoever.</p><p><strong>What students get on Job Raahi:</strong><br>\u2022 Registration is completely free<br>\u2022 Job applications are free \u2014 aaj bhi, kal bhi, aur future mein bhi<br>\u2022 Direct interview opportunities from verified employers across India<br>\u2022 City-wise, trade-wise, and skill-set-based job search<br>\u2022 Regular WhatsApp job alerts for new openings</p><p>Currently, the platform has <strong>3,000+ active job openings</strong> across manufacturing, automotive, electrical, aerospace, operations, and technical sectors \u2014 with new vacancies added regularly.</p><p>We work with reputed employers such as <strong>Amazon, JK Tyre, MG Motor, Ecozen Solutions, myTVS, Amber Group, Agile Robots, Indraprastha Gas Limited, and WSP</strong>, among others.</p><p><strong>How students can get started:</strong><br>\u2022 Download the Job Raahi app<br>\u2022 Complete registration and create their profile<br>\u2022 Apply directly to suitable job openings<br>\u2022 If profile matches, employer contacts them for interview</p><p>You are welcome to share this information with your faculty, admin team, or directly with students.</p><p><strong>Platform Link:</strong> <a href='https://www.YOUR_SENDER.com/'>https://www.YOUR_SENDER.com/</a></p><p>Looking forward to supporting your students with the right opportunities. Please feel free to connect anytime.</p><p>Thank you<br>Gargi \u2013 BDE<br>Job Raahi</p>\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "api-key",
              "value": "YOUR_BREVO_API_KEY"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "84353a2c-0e54-49f7-a1f6-07e4f53040ff",
      "name": "Brevo \u2014 Reassurance Email",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "ACTION REQUIRED: Replace PASTE_YOUR_BREVO_API_KEY_HERE with your actual Brevo API key (same key as the Opportunity Email node).",
      "position": [
        272,
        592
      ],
      "parameters": {
        "url": "https://api.brevo.com/v3/smtp/email",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"sender\": {\n    \"name\": \"JobRaahi Team\",\n    \"email\": \"YOUR_SENDER_EMAIL@example.com\"\n  },\n  \"to\": [\n    {\n      \"email\": \"{{ $('Loop Over Colleges').item.json['Coordinator Email'] }}\",\n      \"name\": \"{{ $('Loop Over Colleges').item.json['Coordinator Name'] }}\"\n    }\n  ],\n  \"subject\": \"Thank You from Job Raahi \u2014 Here for You Whenever the Need Arises\",\n  \"htmlContent\": \"<p>Dear Sir/Madam,</p><p>Thank you for taking the time to speak with us today.</p><p>I completely understand that there may not be an immediate requirement at your end right now \u2014 and that is perfectly fine.</p><p>I am Gargi from Job Raahi \u2014 a free digital job portal designed for ITI, Polytechnic, and entry-level candidates. The platform connects students directly with verified employers across India at absolutely no charge \u2014 no placement fees today, and no fees in the future either.</p><p><strong>At a glance \u2014 what Job Raahi offers:</strong><br>\u2022 3,000+ active job openings across manufacturing, automotive, electrical, aerospace, and operations<br>\u2022 City-wise, trade-wise, and skill-set-based job search for students<br>\u2022 Direct employer connect \u2014 no middlemen, no charges<br>\u2022 Regular WhatsApp job alerts</p><p>Whenever your students are exploring opportunities in the future, Job Raahi will be there as a platform they can rely on \u2014 free of cost, always.</p><p><strong>Platform Link:</strong> <a href='https://www.YOUR_SENDER.com/'>https://www.YOUR_SENDER.com/</a></p><p>We would be happy to collaborate whenever suitable. Wishing you and your institution all the best!</p><p>Thank you<br>Gargi \u2013 BDE<br>Job Raahi</p>\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "api-key",
              "value": "YOUR_BREVO_API_KEY"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b7c70045-5719-470c-845d-d2e20e694986",
      "name": "IF \u2014 2nd Attempt?",
      "type": "n8n-nodes-base.if",
      "notes": "Checks the original Airtable record's Call Status. TRUE [0] = Call Status was 'No Answer - 1' meaning this is the SECOND failed attempt \u2192 Dead Contact. FALSE [1] = Call Status was empty, this is the FIRST failed attempt \u2192 send email, mark No Answer - 1, retry in 3 days.",
      "position": [
        -192,
        816
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond-second-attempt",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ Number($('Airtable \u2014 Get ITI Colleges').item.json['Call Attempts'] ?? 0) }}",
              "rightValue": 1
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "c43a4580-0bbb-492e-bf83-0c961c7541b7",
      "name": "Brevo \u2014 No Answer Email",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Sent after FIRST failed attempt. Informs the coordinator we tried calling and will try again in a few days. ACTION REQUIRED: Replace PASTE_YOUR_BREVO_API_KEY_HERE.",
      "position": [
        224,
        1024
      ],
      "parameters": {
        "url": "https://api.brevo.com/v3/smtp/email",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"sender\": {\n    \"name\": \"JobRaahi Team\",\n    \"email\": \"YOUR_SENDER_EMAIL@example.com\"\n  },\n  \"to\": [\n    {\n      \"email\": \"{{ $('Loop Over Colleges').item.json['Coordinator Email'] }}\",\n      \"name\": \"{{ $('Loop Over Colleges').item.json['Coordinator Name'] }}\"\n    }\n  ],\n  \"subject\": \"Introduction to Job Raahi \u2014 Placement Support for ITI & Polytechnic Students\",\n  \"htmlContent\": \"<p>Dear Sir/Madam,</p><p>Hope you are doing well.</p><p>I tried reaching out to you today. I am Gargi from Job Raahi \u2014 a free digital job portal dedicated to ITI, Polytechnic, and entry-level candidates across India.</p><p>Job Raahi connects students directly with verified employers \u2014 no placement fees, no hidden charges. Aaj nahi, kal nahi, future mein bhi koi charge nahi hoga.</p><p><strong>What students can do on Job Raahi:</strong><br>\u2022 Register for free and build their job profile<br>\u2022 Search jobs by city, trade, skill set, or industry preference<br>\u2022 Apply directly to opportunities \u2014 no middlemen<br>\u2022 Get interviewed directly by employers when profile matches<br>\u2022 Receive regular WhatsApp job alerts</p><p>The platform currently has <strong>3,000+ active openings</strong> across manufacturing, automotive, electrical, aerospace, operations, and technical sectors \u2014 with new vacancies added regularly.</p><p><strong>Platform Link:</strong> <a href='https://www.YOUR_SENDER.com/'>https://www.YOUR_SENDER.com/</a></p><p>We would love to connect and support your students with the right placement opportunities. Please feel free to call or reply to this email at your convenience.</p><p>Thank you<br>Gargi \u2013 BDE<br>Job Raahi</p>\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "api-key",
              "value": "YOUR_BREVO_API_KEY"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "8df05b99-04e7-4492-8e6e-a9b5c52791f9",
      "name": "Airtable update \u2014No answer",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        496,
        1024
      ],
      "parameters": {
        "url": "=https://api.airtable.com/v0/YOUR_BASE_ID/ITI%20Colleges/{{ $('Loop Over Colleges').item.json.id }}",
        "method": "PATCH",
        "options": {},
        "jsonBody": "={\n  \"fields\": {\n    \"{{ (Number($('Loop Over Colleges').item.json['Call Attempts'] ?? 0)) + 1 }},\n    \"Call Status\": \"No Answer\",\n    \"Last Called\": \"{{ $now.toUTC().toISO().split('T')[0] }}\"\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.4
    },
    {
      "id": "11501ee5-f0ca-4f57-b0c1-604fb36600f0",
      "name": "Airtable update \u2014 Interested",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        480,
        208
      ],
      "parameters": {
        "url": "=https://api.airtable.com/v0/YOUR_BASE_ID/ITI%20Colleges/{{ $('Airtable \u2014 Get ITI Colleges').item.json.id }}",
        "method": "PATCH",
        "options": {},
        "jsonBody": "={\n  \"fields\": {\n    \"Call Status\": \"Interested\",\n    \"Last Called\": \"{{ $now.toISODate() }}\",\n    \"Call Attempts\": {{ Number($('Airtable \u2014 Get ITI Colleges').item.json['Call Attempts'] ?? 0) + 1 }}\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.4
    },
    {
      "id": "ddac2a51-44c2-4285-b914-b0a3c7e9079c",
      "name": "Airtable update - Not Interested",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        512,
        592
      ],
      "parameters": {
        "url": "=https://api.airtable.com/v0/YOUR_BASE_ID/ITI%20Colleges/{{ $('Airtable \u2014 Get ITI Colleges').item.json.id }}",
        "method": "PATCH",
        "options": {},
        "jsonBody": "={\n  \"fields\": {\n    \"Call Status\": \"Not Interested\",\n    \"Call Attempts\": {{ ($('Airtable \u2014 Get ITI Colleges').item.json['Call Attempts'] || 0) + 1 }},\n\"Last Called\": \"{{ $now.toUTC().toISO().split('T')[0] }}\"\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.4
    },
    {
      "id": "8b0871fe-be5a-4d27-98a8-50d280534bf1",
      "name": "Airtable update - Dead Contact",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        512,
        800
      ],
      "parameters": {
        "url": "=https://api.airtable.com/v0/YOUR_BASE_ID/ITI%20Colleges/{{ $('Airtable \u2014 Get ITI Colleges').item.json.id }}",
        "method": "PATCH",
        "options": {},
        "jsonBody": "={\n  \"fields\": {\n    \"Call Status\": \"Dead Contact\",\n    \"Last Called\": \"{{ $now.toISODate() }}\",\n    \"Call Attempts\": {{ Number($('Airtable \u2014 Get ITI Colleges').item.json['Call Attempts'] ?? 0) + 1 }}\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.4
    },
    {
      "id": "6c6d683a-d189-4c6d-aea2-2c8053b3903b",
      "name": "Schedule \u2014 Daily 11AM IST",
      "type": "n8n-nodes-base.scheduleTrigger",
      "notes": "Runs every day at 9:00 AM IST (3:30 AM UTC). To test manually, use the Execute Workflow button instead.",
      "position": [
        -2064,
        608
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 30 5 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "247abde4-b441-4fcf-ab4c-672aaebc4868",
      "name": "Skip if Called Recently",
      "type": "n8n-nodes-base.if",
      "position": [
        -1312,
        640
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "abb660e6-aa1a-4dbf-8a30-0f4fdff6062a",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $json['Last Called'] ? $now.diff(DateTime.fromISO($json['Last Called']), 'days').days : 999 }}",
              "rightValue": 3
            },
            {
              "id": "19775958-1ab5-44f7-a7f7-db76bee7e693",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json['Call Status'] ?? '' }}",
              "rightValue": "Interested"
            },
            {
              "id": "4a831d44-7540-4b03-8a7e-59cdcd0e746b",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json['Call Status'] ?? '' }}",
              "rightValue": "Not Interested"
            },
            {
              "id": "c4773a33-3e9a-448d-954b-fa5b84211605",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json['Call Status'] ?? '' }}",
              "rightValue": "Dead Contact"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "e91a8a51-2e6f-4cb7-a5e0-6247f34582e9",
      "name": "Brevo \u2014 Dead Contact Email",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        240,
        800
      ],
      "parameters": {
        "url": "https://api.brevo.com/v3/smtp/email",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"sender\": {\n    \"name\": \"JobRaahi Team\",\n    \"email\": \"YOUR_SENDER_EMAIL@example.com\"\n  },\n  \"to\": [\n    {\n      \"email\": \"{{ $('Loop Over Colleges').item.json['Coordinator Email'] }}\",\n      \"name\": \"{{ $('Loop Over Colleges').item.json['Coordinator Name'] }}\"\n    }\n  ],\n  \"subject\": \"Final Follow-up \u2014 Job Raahi Placement Platform for Your Students\",\n  \"htmlContent\": \"<p>Dear Sir/Madam,</p><p>Hope you are doing well.</p><p>We attempted to connect with you twice regarding Job Raahi, a free digital job portal supporting ITI, Polytechnic, and entry-level students across India. Since we could not reach you over the call, we are briefly sharing our details over email for your reference.</p><p><strong>About Job Raahi \u2014 Quick Summary:</strong><br>\u2022 Pan-India job platform with 3,000+ active openings<br>\u2022 Sectors: Manufacturing, Automotive, Electrical, Aerospace, Operations, Technical<br>\u2022 Students can register, apply, and get interviewed \u2014 completely free<br>\u2022 City-wise, trade-wise, and skill-set-based job search available<br>\u2022 Regular WhatsApp job alerts for new opportunities<br>\u2022 Zero charges \u2014 registration free, applications free, always</p><p><strong>How students can join:</strong><br>\u2022 Download the Job Raahi app<br>\u2022 Complete registration and create profile<br>\u2022 Apply to suitable jobs directly<br>\u2022 Employers contact shortlisted candidates for interviews</p><p><strong>Platform Link:</strong> <a href='https://www.YOUR_SENDER.com/'>https://www.YOUR_SENDER.com/</a></p><p>If your institution would like to explore placement support opportunities for your students at any point in the future, we would be glad to connect at a time that is convenient for you.</p><p>Thank you for your time. We wish you and your institution all the very best.</p><p>Thank you<br>Gargi \u2013 BDE<br>Job Raahi</p>\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "api-key",
              "value": "YOUR_BREVO_API_KEY"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "77482541-8079-4601-90b7-c53b54c2c95f",
      "name": "Groq \u2014 Analyze Transcript",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Uses Claude Haiku to read the Hindi/Hinglish/English transcript and return YES or NO. max_tokens is 10 because we only need one word back \u2014 keeps cost minimal (~$0.0001 per call analysis).",
      "position": [
        -176,
        416
      ],
      "parameters": {
        "url": "https://api.groq.com/openai/v1/chat/completions",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"model\": \"llama-3.3-70b-versatile\",\n  \"max_tokens\": 1024,\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": {{ JSON.stringify(\"Analyze this call transcript and classify the outcome.\\n\\nTranscript:\\n\" + $json.transcript + \"\\n\\nRespond with ONLY one word:\\n- Interested (coordinator showed interest)\\n- NotInterested (coordinator declined)\\n- NoAnswer (call not picked up or unclear)\") }}\n    }\n  ]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "92c9da5f-f00d-4c17-81d6-a6dd8baca949",
      "name": "Wait - 180sec",
      "type": "n8n-nodes-base.wait",
      "notes": "Waits 5 minutes for the call to complete before fetching the result. Adjust if your calls are consistently shorter or longer. Most calls in call history were 2-4 minutes.",
      "position": [
        -848,
        608
      ],
      "parameters": {
        "amount": 180
      },
      "typeVersion": 1.1
    },
    {
      "id": "5e8cc284-ac48-45e8-b291-c841bc7f6289",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2688,
        256
      ],
      "parameters": {
        "width": 492,
        "height": 668,
        "content": "## Run AI voice outreach from Airtable with Bolna, Groq, Brevo and AiSensy\n\n### How it works\n\nThis workflow automates AI voice outreach campaigns for lead generation. Every day at 11 AM IST, it pulls contacts from Airtable, calls each one using Bolna.ai voice agent, waits for the call to complete, then uses Groq to analyze the call transcript. Based on the analysis, contacts are categorized as Interested, Not Interested, No Answer, or Dead Contact. Each category gets a tailored follow-up email via Brevo and a WhatsApp message via AiSensy. Airtable is updated with the call outcome. No-answer contacts get a second attempt before being marked as dead.\n\n### Outcome categories\n\n- Interested: Opportunity email sent, WhatsApp message sent, Airtable updated\n- Not Interested: Reassurance email sent, Airtable updated\n- No Answer (1st attempt): Follow-up email sent, loops back for retry\n- Dead Contact (2nd failed attempt): Dead contact email sent, Airtable updated"
      },
      "typeVersion": 1
    },
    {
      "id": "ca3dca9f-22da-4b7e-adfb-460de500bf67",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2160,
        416
      ],
      "parameters": {
        "color": 2,
        "width": 1000,
        "height": 516,
        "content": "## Trigger and load contacts\n\nSchedule Trigger runs daily at 11 AM IST. Airtable node pulls all contacts from your outreach table. Loop Over Colleges processes contacts one by one. Skip if Called Recently checks the last_called field and skips contacts called in the past 24 hours."
      },
      "typeVersion": 1
    },
    {
      "id": "3676ce73-a995-4924-a1a6-d2dbd94a74a2",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1120,
        416
      ],
      "parameters": {
        "color": 4,
        "width": 588,
        "height": 356,
        "content": "## Place call and wait for result\n\nBolna.ai Place Call triggers the AI voice agent to call the contact. Wait node pauses the workflow for 180 seconds (3 minutes) to allow the call to complete. Bolna Get Call Status fetches the call result including whether the contact picked up and the full transcript."
      },
      "typeVersion": 1
    },
    {
      "id": "0b48696d-e31f-4cf1-a115-dc2d1d99415d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -512,
        176
      ],
      "parameters": {
        "color": 3,
        "width": 560,
        "height": 864,
        "content": "## Analyze transcript and route\n\nIF Did They Pick Up checks if the call was answered. If yes, Groq Analyze Transcript sends the call transcript to Groq Llama 3.3 which determines if the contact showed interest. IF Interested routes to the appropriate email and Airtable update. If the call was not answered, IF 2nd Attempt checks whether this was the first or second try."
      },
      "typeVersion": 1
    },
    {
      "id": "f7f44609-dcb3-49a6-9db6-644bbaa4ac78",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        -16
      ],
      "parameters": {
        "color": 5,
        "width": 624,
        "height": 1268,
        "content": "## Send follow-up emails and update Airtable\n\nFour outcome branches each send a tailored Brevo email and update the contact status in Airtable. Interested contacts also receive a WhatsApp message via AiSensy. After each update, the workflow loops back to process the next contact in the batch."
      },
      "typeVersion": 1
    },
    {
      "id": "ce8c3829-1998-4854-b32f-e63e4c83ed10",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        64
      ],
      "parameters": {
        "color": 6,
        "width": 476,
        "height": 1320,
        "content": "## Setup Guide\n\n### Step 1 - Airtable\n1. Create an Airtable base with a contacts table\n2. Required columns: name, phone, email, status, last_called, attempt_count\n3. Get your Airtable personal access token from airtable.com/create/tokens\n4. n8n: Credentials - Add - Airtable Token API - paste token - Save\n5. Select your base and table in the Airtable Get node\n6. Update the Airtable URLs in all four update nodes with your base and table IDs\n\n### Step 2 - Bolna.ai Voice Agent\n1. Create an AI voice agent at app.bolna.dev\n2. Configure the agent script, voice, and phone number\n3. Copy your Bolna API key\n4. n8n: Credentials - Add - HTTP Header Auth - Name: Authorization, Value: Bearer YOUR_KEY\n5. Replace YOUR_BOLNA_AGENT_ID in both Bolna nodes with your agent ID\n\n### Step 3 - Groq API Key\n1. console.groq.com - API Keys - Create\n2. Replace YOUR_GROQ_API_KEY in the Groq Analyze Transcript node Authorization header\n\n### Step 4 - Brevo Email\n1. Get your Brevo API key from app.brevo.com - Settings - API Keys\n2. Replace YOUR_BREVO_API_KEY in all four Brevo email nodes\n3. Replace YOUR_SENDER_EMAIL with your verified Brevo sender address\n4. Customize the email templates in each Brevo node body\n\n### Step 5 - AiSensy WhatsApp\n1. Get your API key from AiSensy dashboard\n2. Replace YOUR_AISENSY_API_KEY in the WhatsApp msg node\n3. Create and get approved a WhatsApp message template in AiSensy\n\n### Step 6 - Test\n1. Add 2-3 test contacts to Airtable\n2. Click Test Workflow\n3. Check Airtable for status updates and your email for Brevo messages"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "4c9a67bf-ab8a-4249-9d3d-3eac5f831293",
  "nodeGroups": [],
  "connections": {
    "Wait - 180sec": {
      "main": [
        [
          {
            "node": "Bolna \u2014 Get Call Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF \u2014 Interested?": {
      "main": [
        [
          {
            "node": "Brevo \u2014 Opportunity Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Brevo \u2014 Reassurance Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Colleges": {
      "main": [
        [],
        [
          {
            "node": "Skip if Called Recently",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF \u2014 2nd Attempt?": {
      "main": [
        [
          {
            "node": "Brevo \u2014 Dead Contact Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Brevo \u2014 No Answer Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Bolna.ai \u2014 Place Call": {
      "main": [
        [
          {
            "node": "Wait - 180sec",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Skip if Called Recently": {
      "main": [
        [
          {
            "node": "Loop Over Colleges",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Bolna.ai \u2014 Place Call",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF \u2014 Did They Pick Up?": {
      "main": [
        [
          {
            "node": "Groq \u2014 Analyze Transcript",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "IF \u2014 2nd Attempt?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Airtable \u2014 Get Contacts": {
      "main": [
        [
          {
            "node": "Loop Over Colleges",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Bolna \u2014 Get Call Status": {
      "main": [
        [
          {
            "node": "IF \u2014 Did They Pick Up?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Brevo \u2014 No Answer Email": {
      "main": [
        [
          {
            "node": "Airtable update \u2014No answer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Brevo \u2014 Opportunity Email": {
      "main": [
        [
          {
            "node": "Airtable update \u2014 Interested",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Brevo \u2014 Reassurance Email": {
      "main": [
        [
          {
            "node": "Airtable update - Not Interested",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Groq \u2014 Analyze Transcript": {
      "main": [
        [
          {
            "node": "IF \u2014 Interested?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule \u2014 Daily 11AM IST": {
      "main": [
        [
          {
            "node": "Airtable \u2014 Get Contacts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Airtable update \u2014No answer": {
      "main": [
        [
          {
            "node": "Loop Over Colleges",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Brevo \u2014 Dead Contact Email": {
      "main": [
        [
          {
            "node": "Airtable update - Dead Contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Airtable update - Dead Contact": {
      "main": [
        [
          {
            "node": "Loop Over Colleges",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Airtable update \u2014 Interested": {
      "main": [
        [
          {
            "node": "Loop Over Colleges",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Airtable update - Not Interested": {
      "main": [
        [
          {
            "node": "Loop Over Colleges",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}