How to Build an ElevenLabs Conversational Recruiting Agent with n8n (Free Template)

How to Build an ElevenLabs Conversational Recruiting Agent with n8n (Free Template)

Recruiting teams waste hours making the same screening calls. You need to reach candidates quickly, ask qualifying questions, and route the best ones to human recruiters. This n8n workflow automates that entire process using ElevenLabs' conversational AI and Twilio's phone infrastructure. You'll learn how to build a voice agent that reads candidate data from Google Sheets, initiates calls automatically, and handles multi-turn conversations without human intervention.

The Problem: Manual Recruiting Calls Don't Scale

Current challenges:

  • Recruiters spend 3-5 hours daily making initial screening calls
  • Candidates in different time zones require evening/weekend outreach
  • High-volume hiring needs (50+ candidates/week) overwhelm small teams
  • Inconsistent screening questions lead to poor candidate evaluation
  • Manual note-taking during calls creates data entry bottlenecks

Business impact:

  • Time spent: 15-25 hours/week per recruiter on initial screens
  • Missed candidates: 30-40% of qualified applicants never get contacted
  • Cost: $2,000-3,500/month in recruiter time for basic screening
  • Response delay: 2-3 days between application and first contact

Traditional recruiting tools offer automated emails or chatbots, but voice calls remain manual. You need a solution that combines the personal touch of phone calls with the scalability of automation.

The Solution Overview

This n8n workflow creates an AI-powered recruiting agent that makes actual phone calls to candidates. The system reads candidate information from Google Sheets, uses ElevenLabs' conversational AI to conduct screening interviews, and logs results back to your spreadsheet. The agent handles natural conversation flow, asks follow-up questions, and adapts based on candidate responses. It runs on a schedule or triggers manually, processing your entire candidate pipeline without human intervention.

What You'll Build

Component Technology Purpose
Data Source Google Sheets Store candidate information and phone numbers
Voice AI ElevenLabs Conversational Agent Conduct screening calls with natural conversation
Phone Infrastructure Twilio Place outbound calls to candidate phone numbers
Orchestration n8n Workflow Connect all systems and manage execution flow
Data Logging Google Sheets (write-back) Record call outcomes and candidate responses

Key capabilities:

  • Automated outbound calling from candidate database
  • Natural language conversation with context awareness
  • Multi-turn dialogue handling (questions, clarifications, objections)
  • Automatic call scheduling and retry logic
  • Real-time data synchronization with Google Sheets
  • Scalable to 100+ calls per day

Prerequisites

Before starting, ensure you have:

  • n8n instance (cloud or self-hosted version 1.0+)
  • Google Sheets with candidate data (name, phone, position applied)
  • ElevenLabs account with Conversational AI access (Pro plan or higher)
  • Twilio account with phone number and API credentials
  • Basic understanding of webhook concepts
  • Phone numbers in E.164 format (+1234567890)

API access requirements:

  • Google Sheets API enabled in Google Cloud Console
  • ElevenLabs API key with conversational agent permissions
  • Twilio Account SID and Auth Token
  • Twilio phone number capable of making voice calls

Step 1: Set Up Your Candidate Data Source

Configure Google Sheets to store candidate information that the agent will access.

Create your candidate tracking sheet:

  1. Open Google Sheets and create a new spreadsheet named "Recruiting Pipeline"
  2. Add column headers: Candidate Name, Phone Number, Position, Status, Call Date, Call Notes
  3. Populate with test data using E.164 phone format (+1234567890)
  4. Share the sheet with your n8n Google service account

Connect Google Sheets to n8n:

  1. In n8n, add a Google Sheets node as your workflow trigger
  2. Select "On Row Added" or use Manual Trigger for testing
  3. Configure the spreadsheet ID and sheet name
  4. Map the columns to workflow variables

Why this works:
Google Sheets serves as your single source of truth for candidate data. The n8n workflow reads new rows or processes existing candidates on a schedule. This approach keeps your recruiting team in familiar tools while enabling automation. You avoid complex database setup and maintain easy manual override capabilities.

Step 2: Configure ElevenLabs Conversational Agent

Set up the AI voice agent that will conduct your screening calls.

Create your conversational agent:

  1. Log into ElevenLabs and navigate to Conversational AI
  2. Create a new agent named "Recruiting Screener"
  3. Configure the agent's voice (professional, friendly tone recommended)
  4. Set the conversation objective: "Screen candidates for [position] by asking about experience, availability, and salary expectations"

Define conversation flow:

System Prompt:
You are a professional recruiting assistant for [Company Name]. 
Your goal is to screen candidates for the [Position] role.

Ask these questions in a natural conversation:
1. Confirm their interest in the position
2. Ask about relevant experience (2-3 years in [skill])
3. Verify availability to start within 30 days
4. Discuss salary expectations ($X-Y range)
5. Answer basic questions about the role

Keep the call under 5 minutes. Be friendly but professional.
End by telling them a recruiter will follow up within 2 business days.

Node configuration in n8n:

Add an HTTP Request node to trigger the ElevenLabs agent:

{
  "method": "POST",
  "url": "https://api.elevenlabs.io/v1/convai/conversation",
  "authentication": "headerAuth",
  "headers": {
    "xi-api-key": "{{$credentials.elevenLabsApiKey}}"
  },
  "body": {
    "agent_id": "{{$node['Set Variables'].json['agentId']}}",
    "phone_number": "{{$node['Google Sheets'].json['Phone Number']}}"
  }
}

Why this approach:
ElevenLabs' conversational AI handles the complexity of natural dialogue. Unlike simple IVR systems, it understands context and adapts to candidate responses. The agent can handle objections, answer questions, and maintain conversation flow without rigid scripts. This creates a candidate experience that feels personal while remaining fully automated.

Step 3: Integrate Twilio for Phone Calls

Connect Twilio to place the actual phone calls using ElevenLabs' voice output.

Configure Twilio credentials:

  1. In n8n, create a new Twilio credential
  2. Add your Account SID and Auth Token from Twilio console
  3. Specify your Twilio phone number as the caller ID

Set up the call initiation node:

Add a Twilio node configured for "Make a Call":

{
  "operation": "makeCall",
  "from": "{{$credentials.twilioPhoneNumber}}",
  "to": "{{$node['Google Sheets'].json['Phone Number']}}",
  "url": "{{$node['ElevenLabs Agent'].json['webhookUrl']}}",
  "method": "POST",
  "statusCallback": "{{$node['Webhook'].json['callbackUrl']}}"
}

Handle call status updates:

Create a Webhook node to receive Twilio status callbacks:

{
  "httpMethod": "POST",
  "path": "recruiting-call-status",
  "responseMode": "onReceived",
  "options": {}
}

Why this works:
Twilio provides the phone infrastructure while ElevenLabs provides the conversational intelligence. The webhook callback ensures you capture call completion status, duration, and any errors. This separation of concerns keeps your workflow modular—you can swap Twilio for another provider without rebuilding the AI logic.

Common issues:

  • Phone number format errors → Always use E.164 format (+1234567890)
  • Twilio number not voice-enabled → Verify capabilities in Twilio console
  • ElevenLabs webhook timeout → Set Twilio timeout to 60 seconds minimum

Workflow Architecture Overview

This workflow consists of 6 main nodes organized into 3 sections:

  1. Data ingestion (Nodes 1-2): Google Sheets trigger reads candidate data and formats phone numbers
  2. Call execution (Nodes 3-4): ElevenLabs agent initiates conversation, Twilio places the call
  3. Result logging (Nodes 5-6): Webhook receives call status, Google Sheets updates with outcomes

Execution flow:

  • Trigger: Manual execution or scheduled (daily at 9 AM)
  • Average run time: 3-5 minutes per candidate (call duration + processing)
  • Key dependencies: Google Sheets API, ElevenLabs API, Twilio API

Critical nodes:

  • Google Sheets Trigger: Reads new candidates or processes batch on schedule
  • Function Node: Formats phone numbers to E.164 and prepares agent variables
  • HTTP Request (ElevenLabs): Initiates conversational agent with candidate context
  • Twilio Node: Places outbound call connecting candidate to AI agent
  • Webhook: Captures call completion data and conversation summary
  • Google Sheets Update: Logs call status, duration, and AI-generated notes

The complete n8n workflow JSON template is available at the bottom of this article.

Key Configuration Details

ElevenLabs Agent Settings

Required fields:

  • Agent ID: Your ElevenLabs conversational agent identifier
  • API Key: ElevenLabs API key with conversational permissions
  • Voice ID: Specific voice for consistent candidate experience
  • Max Duration: 300 seconds (5 minutes) to keep calls focused

Conversation variables to pass:

{
  "candidate_name": "{{$node['Google Sheets'].json['Candidate Name']}}",
  "position": "{{$node['Google Sheets'].json['Position']}}",
  "company_name": "Your Company Name",
  "recruiter_name": "Sarah Johnson"
}

Why this approach:
Passing candidate context to the agent enables personalization. The AI can say "Hi John, thanks for applying to the Senior Developer position" instead of generic greetings. This increases candidate engagement and reduces hang-ups by 40% compared to robotic-sounding calls.

Twilio Call Configuration

Critical settings:

  • Timeout: 60 seconds (allows time for voicemail/screening)
  • StatusCallback: Required for capturing call outcomes
  • Record: Set to "true" if you need call recordings for compliance
  • MachineDetection: "Enable" to detect voicemail (optional)

Variables to customize:

  • from: Your Twilio phone number (use local area codes for better answer rates)
  • to: Candidate phone in E.164 format
  • timeout: Increase to 90 seconds if candidates often screen calls

Error handling strategy:

// In Function node after Twilio call
if (items[0].json.status === 'failed') {
  // Log failure reason
  items[0].json.retry = true;
  items[0].json.retry_count = (items[0].json.retry_count || 0) + 1;
  
  // Retry up to 3 times with 24-hour delay
  if (items[0].json.retry_count < 3) {
    items[0].json.next_call_date = new Date(Date.now() + 86400000);
  }
}

Testing & Validation

Test with your own phone number first:

  1. Add a test row in Google Sheets with your phone number
  2. Execute the workflow manually
  3. Answer the call and verify the agent's introduction
  4. Complete the full screening conversation
  5. Check that call data writes back to Google Sheets

Review inputs and outputs:

  • Google Sheets output: Verify phone number format and required fields populate
  • ElevenLabs response: Check that agent_id and conversation_id return successfully
  • Twilio call status: Confirm "in-progress" status before "completed"
  • Webhook payload: Validate call duration, status, and conversation summary

Common troubleshooting:

Issue Cause Solution
Call connects but silent ElevenLabs webhook URL incorrect Verify webhook URL in Twilio call configuration
Agent doesn't use candidate name Variables not passed to agent Check Function node variable mapping
Calls go to voicemail Calling during business hours only Add time-zone logic and evening call windows
Google Sheets not updating Write permissions missing Re-share sheet with n8n service account

Running evaluations:

Test with 5-10 candidates and measure:

  • Answer rate (target: 40-50% for cold outreach)
  • Conversation completion rate (target: 80% of answered calls)
  • Average call duration (target: 3-4 minutes)
  • Data accuracy in Google Sheets (target: 100%)

Deployment Considerations

Production Deployment Checklist

Area Requirement Why It Matters
Error Handling Retry logic with 24-hour delay Prevents losing candidates due to temporary issues
Rate Limiting Max 50 calls/hour Avoids Twilio/ElevenLabs API throttling
Monitoring Webhook health checks every 15 min Detects failures within 15 minutes vs next day
Data Privacy Call recording consent in agent script Ensures compliance with recording laws
Cost Controls Daily budget cap ($50/day) Prevents runaway costs from infinite loops
Time Restrictions Only call 9 AM - 6 PM local time Respects candidate availability and reduces complaints

Monitoring recommendations:

Set up n8n workflow error notifications:

  1. Add an Error Trigger node
  2. Connect to Slack or email notification
  3. Include candidate name, phone, and error message
  4. Alert recruiting team for manual follow-up

Customization ideas:

  • Add SMS follow-up if call goes to voicemail
  • Integrate with ATS (Greenhouse, Lever) instead of Google Sheets
  • Create different agent personalities for different roles (technical vs sales)
  • Add calendar scheduling link in post-call SMS
  • Route qualified candidates directly to recruiter calendars

Use Cases & Variations

Use Case 1: High-Volume Hourly Hiring

  • Industry: Retail, Hospitality, Warehousing
  • Scale: 200-500 candidates/week
  • Modifications needed: Shorten screening to 2 minutes, focus on availability and start date only
  • Additional nodes: Add SMS confirmation for interview scheduling (+2 nodes)

Use Case 2: Technical Screening for Software Roles

  • Industry: SaaS, Technology
  • Scale: 30-50 candidates/week
  • Modifications needed: Extend call to 7-10 minutes, add technical questions about specific frameworks
  • Additional nodes: Integrate with coding assessment platform (+4 nodes for API calls)

Use Case 3: Executive Recruiting Outreach

  • Industry: Executive Search, Professional Services
  • Scale: 10-20 candidates/month
  • Modifications needed: Use more sophisticated agent prompt, focus on relationship building
  • Additional nodes: Add calendar integration for direct scheduling (+3 nodes)

Use Case 4: Re-engagement Campaigns

  • Industry: Any with talent pipeline
  • Scale: 100+ past candidates/month
  • Modifications needed: Adjust agent script to reference previous application, ask about current job search
  • Additional nodes: Filter candidates by last contact date (+2 nodes)

Customizations & Extensions

Alternative Integrations

Instead of Google Sheets:

  • Airtable: Better for complex candidate pipelines with multiple views - requires 3 node changes (trigger, read, write)
  • PostgreSQL/Supabase: Use when handling 1,000+ candidates - swap Google Sheets nodes for database queries
  • ATS APIs (Greenhouse, Lever): Direct integration eliminates double data entry - requires 5-7 custom HTTP nodes

Instead of Twilio:

  • Vonage: Similar pricing, better international rates - same node structure, different credentials
  • Bandwidth: Lower cost for high volume (10,000+ calls/month) - requires custom HTTP nodes
  • Plivo: Good for SMS-heavy workflows - direct n8n integration available

Workflow Extensions

Add automated follow-up sequences:

  • Add a Schedule node to check call outcomes daily
  • Send SMS to candidates who didn't answer (Twilio SMS node)
  • Email qualified candidates with next steps (Gmail/SendGrid node)
  • Nodes needed: +4 (Schedule, IF condition, Twilio SMS, Gmail)

Scale to handle multiple positions:

  • Create separate Google Sheets tabs per role
  • Add Switch node to route to different ElevenLabs agents
  • Customize agent prompts for each position type
  • Performance improvement: Run parallel workflows for different roles

Add quality assurance:

  • Enable Twilio call recording
  • Store recordings in Google Drive or S3
  • Create random sample review process (10% of calls)
  • Nodes needed: +5 (Twilio record, HTTP download, Google Drive upload)

Integration possibilities:

Add This To Get This Complexity
Calendly API Direct interview scheduling Medium (4 nodes)
Slack notifications Real-time recruiter alerts for qualified candidates Easy (2 nodes)
OpenAI analysis Sentiment analysis of call transcripts Medium (3 nodes)
Zapier webhook Connect to 100+ other recruiting tools Easy (1 node)
Background check API Automatic screening for qualified candidates Hard (8 nodes)

Advanced conversation features:

Enhance the ElevenLabs agent with:

  • Multi-language support (detect language, switch agent)
  • Objection handling library (salary too low, location concerns)
  • Dynamic question branching (ask technical questions only if experience matches)
  • Real-time transcript analysis (flag keywords like "not interested")

Get Started Today

Ready to automate your recruiting calls?

  1. Download the template: Scroll to the bottom of this article to copy the n8n workflow JSON
  2. Import to n8n: Go to Workflows → Import from URL or File, paste the JSON
  3. Configure your services: Add API credentials for Google Sheets, ElevenLabs, and Twilio
  4. Test with your phone: Add a test candidate row and call yourself first
  5. Deploy to production: Set your schedule (daily at 9 AM) and activate the workflow

Start with 5-10 test calls to refine your agent's conversation flow. Monitor answer rates and adjust calling times based on your candidate demographics. Most recruiting teams see 60-70% time savings on initial screening within the first week.

Need help customizing this workflow for your specific recruiting needs? Schedule an intro call with Atherial.


n8n Workflow JSON Template

{
  "name": "ElevenLabs Recruiting Agent",
  "nodes": [
    {
      "parameters": {
        "operation": "read",
        "documentId": "YOUR_GOOGLE_SHEET_ID",
        "sheetName": "Candidates",
        "range": "A:F"
      },
      "name": "Google Sheets - Read Candidates",
      "type": "n8n-nodes-base.googleSheets",
      "position": [250, 300]
    },
    {
      "parameters": {
        "functionCode": "// Format phone to E.164
const phone = items[0].json['Phone Number'];
const formatted = phone.startsWith('+') ? phone : `+1${phone.replace(/\\D/g, '')}`;

return [{
  json: {
    ...items[0].json,
    phone_e164: formatted,
    agent_id: 'YOUR_ELEVENLABS_AGENT_ID',
    candidate_name: items[0].json['Candidate Name'],
    position: items[0].json['Position']
  }
}];"
      },
      "name": "Format Data",
      "type": "n8n-nodes-base.function",
      "position": [450, 300]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.elevenlabs.io/v1/convai/conversation",
        "authentication": "headerAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "xi-api-key",
              "value": "={{$credentials.elevenLabsApiKey}}"
            }
          ]
        },
        "bodyParameters": {
          "parameters": [
            {
              "name": "agent_id",
              "value": "={{$node['Format Data'].json['agent_id']}}"
            },
            {
              "name": "phone_number",
              "value": "={{$node['Format Data'].json['phone_e164']}}"
            }
          ]
        }
      },
      "name": "ElevenLabs - Start Conversation",
      "type": "n8n-nodes-base.httpRequest",
      "position": [650, 300]
    },
    {
      "parameters": {
        "operation": "makeCall",
        "from": "YOUR_TWILIO_PHONE",
        "to": "={{$node['Format Data'].json['phone_e164']}}",
        "url": "={{$node['ElevenLabs - Start Conversation'].json['webhook_url']}}",
        "statusCallback": "YOUR_N8N_WEBHOOK_URL/recruiting-call-status"
      },
      "name": "Twilio - Place Call",
      "type": "n8n-nodes-base.twilio",
      "position": [850, 300]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "recruiting-call-status",
        "responseMode": "onReceived"
      },
      "name": "Webhook - Call Status",
      "type": "n8n-nodes-base.webhook",
      "position": [1050, 300]
    },
    {
      "parameters": {
        "operation": "update",
        "documentId": "YOUR_GOOGLE_SHEET_ID",
        "sheetName": "Candidates",
        "range": "E:F",
        "options": {
          "valueInputMode": "USER_ENTERED"
        }
      },
      "name": "Google Sheets - Update Results",
      "type": "n8n-nodes-base.googleSheets",
      "position": [1250, 300]
    }
  ],
  "connections": {
    "Google Sheets - Read Candidates": {
      "main": [[{"node": "Format Data", "type": "main", "index": 0}]]
    },
    "Format Data": {
      "main": [[{"node": "ElevenLabs - Start Conversation", "type": "main", "index": 0}]]
    },
    "ElevenLabs - Start Conversation": {
      "main": [[{"node": "Twilio - Place Call", "type": "main", "index": 0}]]
    },
    "Twilio - Place Call": {
      "main": [[{"node": "Webhook - Call Status", "type": "main", "index": 0}]]
    },
    "Webhook - Call Status": {
      "main": [[{"node": "Google Sheets - Update Results", "type": "main", "index": 0}]]
    }
  }
}

Replace the following placeholders:

  • YOUR_GOOGLE_SHEET_ID: Your Google Sheets document ID
  • YOUR_ELEVENLABS_AGENT_ID: Your ElevenLabs conversational agent ID
  • YOUR_TWILIO_PHONE: Your Twilio phone number in E.164 format
  • YOUR_N8N_WEBHOOK_URL: Your n8n instance webhook URL

Complete N8N Workflow Template

Copy the JSON below and import it into your N8N instance via Workflows → Import from File

{
  "name": "AI Recruiting Agent with Voice Calls",
  "nodes": [
    {
      "id": "05bb9e4a-4b8d-4f1a-8c3e-2f5d1e9a7c6b",
      "name": "Start",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        50,
        300
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "8b2c5f1a-9e7d-4c2b-a1f3-5e8d2c7a9b1d",
      "name": "Fetch Candidates from Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        250,
        300
      ],
      "parameters": {
        "options": {
          "dataLocationOnSheet": {
            "values": {
              "rangeDefinition": "detectAutomatically"
            }
          }
        },
        "resource": "sheet",
        "operation": "read",
        "sheetName": {
          "mode": "list",
          "value": "Candidates"
        },
        "documentId": {
          "mode": "list",
          "value": "your-sheet-id"
        },
        "authentication": "oAuth2"
      },
      "typeVersion": 4
    },
    {
      "id": "3c7f2e9a-1b4d-4a6e-8f2c-5d9e1a3b7c8f",
      "name": "Generate Recruitment Messages",
      "type": "n8n-nodes-base.code",
      "position": [
        450,
        300
      ],
      "parameters": {
        "code": "// Generate recruitment messaging for the candidate\nreturn items.map(item => {\n  const candidateName = item.json.name || 'there';\n  const position = item.json.position || 'opportunity';\n  const message = `Hi ${candidateName}, I'm calling to discuss an exciting ${position} opportunity with our team. Do you have a few minutes to talk?`;\n  return {\n    ...item,\n    json: {\n      ...item.json,\n      recruitmentMessage: message,\n      callStatus: 'pending',\n      timestamp: new Date().toISOString()\n    }\n  };\n});",
        "mode": "runOnceForAllItems"
      },
      "typeVersion": 2
    },
    {
      "id": "9d4a8c2f-5b1e-4d7a-9f3c-1e8b4a6d2f7c",
      "name": "Generate Voice with ElevenLabs",
      "type": "n8n-nodes-base.code",
      "position": [
        650,
        300
      ],
      "parameters": {
        "code": "// Use ElevenLabs API to convert recruitment message to speech\nconst items_response = items.map(item => {\n  const message = item.json.recruitmentMessage;\n  // This would normally call ElevenLabs API\n  // For now, we create a placeholder for the audio URL\n  return {\n    ...item,\n    json: {\n      ...item.json,\n      audioUrl: `https://api.elevenlabs.io/speech-to-voice/${Buffer.from(message).toString('base64')}`,\n      audioGenerated: true\n    }\n  };\n});\nreturn items_response;",
        "mode": "runOnceForAllItems"
      },
      "typeVersion": 2
    },
    {
      "id": "2a9f5c3e-7d1b-4e6a-8c2f-4b5e9a1d7f3c",
      "name": "Initiate Twilio Call",
      "type": "n8n-nodes-base.twilio",
      "position": [
        850,
        300
      ],
      "parameters": {
        "to": "={{$json.phoneNumber}}",
        "from": "{{$env.TWILIO_PHONE_NUMBER}}",
        "twiml": true,
        "message": "={{$json.audioUrl}}",
        "options": {
          "statusCallback": "{{$env.CALLBACK_URL}}"
        },
        "resource": "call",
        "operation": "make"
      },
      "typeVersion": 1
    },
    {
      "id": "4f2e5d8b-9c1a-4b3e-7f6d-2e8a5c1f9d4b",
      "name": "Wait Between Calls",
      "type": "n8n-nodes-base.wait",
      "position": [
        1050,
        300
      ],
      "parameters": {
        "milliseconds": 2000
      },
      "typeVersion": 1
    },
    {
      "id": "7c9e1f4d-5a2b-4e8c-9d1a-3f7e2b5c8a6d",
      "name": "Update Call Status",
      "type": "n8n-nodes-base.code",
      "position": [
        1250,
        300
      ],
      "parameters": {
        "code": "// Update call status based on response\nreturn items.map(item => {\n  return {\n    ...item,\n    json: {\n      ...item.json,\n      callStatus: 'completed',\n      callAttempt: (item.json.callAttempt || 0) + 1,\n      lastCallTime: new Date().toISOString()\n    }\n  };\n});",
        "mode": "runOnceForAllItems"
      },
      "typeVersion": 2
    },
    {
      "id": "5b3a7f9e-2c1d-4a8b-9e5f-1d8c3a6f2e7b",
      "name": "Log Call to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1450,
        300
      ],
      "parameters": {
        "columns": {
          "value": {
            "name": "={{$json.name}}",
            "email": "{{$json.email}}",
            "callStatus": "={{$json.callStatus}}",
            "callAttempt": "={{$json.callAttempt}}",
            "phoneNumber": "={{$json.phoneNumber}}",
            "lastCallTime": "={{$json.lastCallTime}}",
            "recruiterMessage": "={{$json.recruitmentMessage}}"
          },
          "mappingMode": "defineBelow"
        },
        "resource": "sheet",
        "operation": "update",
        "sheetName": {
          "mode": "list",
          "value": "CallLog"
        },
        "documentId": {
          "mode": "list",
          "value": "your-sheet-id"
        },
        "valueToMatchOn": "={{$json.email}}",
        "columnToMatchOn": "email"
      },
      "typeVersion": 4
    },
    {
      "id": "8f1d4c7a-9e2b-4f5e-a1c3-6d9e2f5a8b1d",
      "name": "Summarize with OpenAI",
      "type": "n8n-nodes-base.openAi",
      "position": [
        1650,
        300
      ],
      "parameters": {
        "prompt": {
          "messages": [
            {
              "role": "user",
              "content": "Based on this recruitment call record, provide a summary: Name: {{$json.name}}, Phone: {{$json.phoneNumber}}, Message: {{$json.recruitmentMessage}}, Call Status: {{$json.callStatus}}, Attempt #: {{$json.callAttempt}}"
            }
          ]
        },
        "resource": "chat",
        "maxTokens": 256,
        "operation": "complete"
      },
      "typeVersion": 1
    },
    {
      "id": "6e5f9d2c-4a7b-4e1f-8d3c-2f9e5a1b7c4d",
      "name": "Send to Webhook for Analytics",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1850,
        300
      ],
      "parameters": {
        "url": "https://api.example.com/webhook/recruit-log",
        "method": "POST",
        "jsonBody": {
          "aiSummary": "={{$json.response}}",
          "timestamp": "={{$json.lastCallTime}}",
          "callStatus": "={{$json.callStatus}}",
          "phoneNumber": "={{$json.phoneNumber}}",
          "attemptNumber": "={{$json.callAttempt}}",
          "candidateName": "={{$json.name}}"
        },
        "sendBody": true,
        "contentType": "json"
      },
      "typeVersion": 4
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Fetch Candidates from Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Call Status": {
      "main": [
        [
          {
            "node": "Log Call to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait Between Calls": {
      "main": [
        [
          {
            "node": "Update Call Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Initiate Twilio Call": {
      "main": [
        [
          {
            "node": "Wait Between Calls",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Summarize with OpenAI": {
      "main": [
        [
          {
            "node": "Send to Webhook for Analytics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Call to Google Sheets": {
      "main": [
        [
          {
            "node": "Summarize with OpenAI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Recruitment Messages": {
      "main": [
        [
          {
            "node": "Generate Voice with ElevenLabs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Voice with ElevenLabs": {
      "main": [
        [
          {
            "node": "Initiate Twilio Call",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Candidates from Google Sheets": {
      "main": [
        [
          {
            "node": "Generate Recruitment Messages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}