Building an Outbound Voice AI Agent (Belle) in 10 Minutes πŸ—οΈ

What We’re Building :rocket:

A fully automated outbound voice agent that

  • dials prospects, greets them by name and delivers a scripted offer
  • converses in real time through an Ultravox WebSocket session
  • is orchestrated by an n8n workflow (free trial – affiliate link) that glues together
    • Google Sheets – lead list (FirstName, PhoneE164, Status)
    • Ultravox – AI voice agent (free sign-up)
    • Twilio – telephony with dynamic TwiML (free sign-up)

The same workflow can run a single test call or fan out to batch campaigns with no human intervention.


How It Works :hammer_and_wrench:

  1. Trigger – manual click, schedule or webhook starts the workflow.
  2. Fetch Lead – Google Sheets node pulls the next row.
  3. Spin Up Voice Session – HTTP node opens an Ultravox WebSocket and returns a session_url.
  4. Assemble TwiML – n8n builds a <Dial><Number> block that bridges Twilio to the Ultravox session.
  5. Place Call – Twilio dials the prospect and hands over the TwiML.
  6. Post-Call Actions – update the sheet, log transcripts or branch to follow-ups.

What This Unlocks :unlocked:

  • Hyper-scalable outreach – queue hundreds of concurrent calls
  • Consistent compliance – every sentence comes from your approved system prompt
  • Instant iteration – tweak Belle’s voice or script in seconds
  • Rich analytics – capture recordings, transcripts and outcomes for A/B tests

Typical Use Cases

Scenario Example
Sales blitz Solar rebate campaign (Belle)
Collections Friendly payment-due reminders
Customer research Automated NPS surveys
On-boarding β€œWelcome” walkthrough calls for new app users

Prerequisites :memo:

  • n8n cloud or self-hosted instance with credential manager – get a free trial via this affiliate link: Powerful Workflow Automation Software & Tools - n8n
  • Google Cloud service account with Sheets API access
  • Ultravox account, API key and one agent (voice + prompt)
  • Twilio account with an Australian voice-enabled number
  • Basic JSON skills and a text editor

Step-by-Step Guide :stopwatch:

1 – Prepare the Lead Sheet
  • Create a sheet called OutboundCalls.
  • Add columns: FirstName, PhoneE164 (e.g. +61212345678), Status.
  • Share the sheet with your service-account email (Editor access).
2 – Create the Ultravox Agent
  1. Ultravox console β†’ Agents β†’ New Agent.
  2. Name: AI Belle.
  3. Voice: any neural French-accent voice.
  4. System prompt:
You are Belle, a friendly professional solar-energy outreach agent.
Greet the user by first name, ask two qualifying questions,
then end politely if uninterested.
  1. Save and copy the Agent ID for n8n.
3 – Configure Twilio
  • Buy or verify a voice-capable AU number.
  • Note your Account SID, Auth Token and Phone Number.
  • Voice β†’ Settings: allow HTTP POST from your n8n URL.
4 – Import the n8n Workflow
  • In n8n: File β†’ Import from File β†’ outbound.json (save the JSON from this guide as outbound.json).
5 – Set Up Credentials in n8n
Node Credential Type Fields
Google Sheets OAuth2 Service Account Client Email, Private Key
Ultravox HTTP Generic API Key Authorization: Bearer <token>
Twilio OAuth Account SID, Auth Token
6 – Node-by-Node Customisation

Trigger – start with Manual, switch to Cron later.

Retrieve Call Details – operation Lookup where Status is blank, return first row.

Create Ultravox Session – HTTP POST

POST https://api.ultravox.ai/v1/agents/{{ ULTRAVOX_AGENT_ID }}/websocket
{
  "sessionParameters": {
    "agentPromptOverride": "Hi {{ $json.FirstName }} …",
    "audio": { "sampleRate": 8000 }
  }
}

Set Variables

firstName   ← {{$json.FirstName}}
targetPhone ← {{$json.PhoneE164}}
sessionUrl  ← response.session_url

Prepare TwiML

<Response>
  <Dial>
    <Number url="{{ $json.sessionUrl }}">{{ $json.targetPhone }}</Number>
  </Dial>
</Response>

Make Call (Twilio node)

  • From: your Twilio number
  • To: ={{$node["Set Variables"].json["targetPhone"]}}
  • TwiML: output of the previous node
7 – Testing
  1. Click Execute Workflow.
  2. Your phone rings – Belle greets you by name.
  3. End the call and mark the sheet row Completed.
8 – Batch Campaign (Optional) πŸ“ž
  • Change Trigger to Cron (e.g. every 5 minutes).
  • Add Split In Batches (size 5) before the Ultravox session to limit concurrency.
9 – Post-Processing Ideas
  • Append call result and timestamp back to the sheet
  • Store transcripts from the Ultravox webhook for sentiment analysis
  • Send a Slack alert with the outcome

Next Steps :seedling:

  • Track connection rate, talk time and conversion against human callers
  • Swap Google Sheets for Airtable or Postgres by changing the β€œFetch Lead” node
  • Add a do-not-call scrub and time-of-day guardrails for AU compliance

Download the full n8n workflow here:

Outbound Call Prompt Template:

## 1. Role Overview  
**You are** `[Agent Name]`, the outbound call agent for `[Company Name]`.  
**Objective**: Reach out to prospects, qualify interest, and arrange next steps on behalf of `[Company Name]`.

## 2. Key Responsibilities  

- **Initiate Calls**  
  - Use Twilio (or your chosen platform) to place outbound voice calls  
  - Open with the approved script  

- **Qualify & Capture Information**  
  - Confirm contact’s name via `{{$json.Name}}` (or equivalent)  
  - Assess interest in the offer or topic at hand  

- **Schedule Next Steps**  
  - Propose meeting slots only when pre-approved  
  - Send calendar invites with correct time zone and link  

- **Log Outcomes**  
  - Record call notes, urgency, and follow-up actions in CRM  

## 3. Persona & Communication Style  

- **Tone**: Polite / Friendly / Professional (choose per brand)  
- **Style**: Clear and efficient – state purpose within 30 seconds  
- **Approach**:  
  - Personalise with the prospect’s name  
  - Respect their time and confirm agreed next steps  

## 4. Core Call Flow  

1. **Greeting & Introduction**  
   > β€œHi `{{$json.Name}}`! This is `[Agent Name]` from `[Company Name]`. I’m calling to share `[brief purpose]`. May I ask you a few quick questions?”  

2. **Qualify & Record**  
   - **Name** (already personalised)  
   - **Company / Context** (if known)  
   - **Contact Info** (phone / email)  
   - **Reason for Call** (brief summary)  
   - **Urgency** (ASAP / By date / Low)  

3. **Next Steps**  
   - **If Pre-approved to Book**  
     > β€œI have two slots on `[Date]` at `[Time1]` and `[Time2]` in `[Time Zone]`. Which works best?”  
   - **If Approval Needed**  
     > β€œI’ll check availability and get back to you within `[timeframe]`.”  

4. **Confirmation & Close**  
   > β€œThanks for your time, `{{$json.Name}}`. I’ll send over a calendar invite and follow up with any details.”  

## 5. Call Note Format  
```yaml
Message for [Executive/Team]:
- Name: {{$json.Name}}
- Company/Role: [If known]
- Contact: [Phone/Email]
- Reason: [Brief summary]
- Urgency: [E.g., Wants reply by Friday]
- Next Steps: [Meeting confirmed / Approval pending]

1 Like