External Publication
Visit Post

The AI That Had to Learn to Say It Was an AI: Building a Production Voice Engine on n8n and Vapi

Tugui's Notes May 27, 2026
Source

It broke on a Tuesday morning. Not dramatically. No red errors, no crash logs. The workflow just quietly stopped detecting when calls ended. The polling loop would initiate a call through Vapi, the lead would pick up, the conversation would happen, they would hang up, and n8n would keep polling. Indefinitely. The call was done. The workflow had no idea.

It took two hours to find the problem. A single Code node was returning data in a format that n8n v1 accepted without complaint. n8n v2 silently rejected it. No error. No warning. Just a workflow that looked like it was running but was not actually doing anything useful.

That moment was the start of a full audit. Every node inspected. Every API endpoint verified. Every expression tested in production. What came out of that process is the May 2026 stable release of an outbound calling system that started as a Reddit post with 120,000 views and is now running live campaigns of 300+ calls per day across 9-hour sessions without interruption.

This is the full story of how it got there.

Who This Was Built For

This system was not built for enterprise call centers with dedicated engineering teams. It was built for the businesses and agencies that fall between too small for a custom solution and too serious to keep dialing leads by hand.

  • Small and medium businesses with online lead forms are the core use case. Someone fills out a contact form on a website, a landing page, or a funnel. Within minutes the AI calls them while the intent is still fresh. It introduces itself, confirms the details from the form, qualifies the opportunity, and either books a meeting directly or routes the contact to a human representative. No manual follow-up. No leads going cold overnight.Digital agencies running outbound campaigns for local clients use the system to replace the first layer of a call center operation.
  • Dental clinics, home service companies, real estate teams, and fitness studios all have the same problem: a list of prospects and no reliable way to contact every one of them quickly. The AI handles the volume. The human team handles the conversations that matter.
  • SaaS companies use it to qualify new signups at the moment of registration, before the lead has time to explore a competitor.
  • E-commerce brands use it to recover abandoned high-ticket carts. Recruiters use it to pre-screen candidates before scheduling a human interview.

The common thread is the same in every case. A person expressed interest. The window to act is short. The AI calls, qualifies, and decides what happens next, automatically.

From Reddit Experiment to Production Architecture

The project started as a personal challenge: build an AI voice agent that could call real prospects, hold a natural conversation, qualify leads, and push structured data to a CRM without writing a custom backend from scratch.

After weeks of testing, debugging dropped webhooks, and working through API version mismatches, a working prototype was shared on the r/n8n subreddit. The post documented the full technical process, from Vapi configuration to Twilio routing to n8n loop management. It collected over 120,000 views and triggered more inbound questions than anything published before or since.

The response confirmed that the demand was real. But the prototype was not production-ready. Over a year of running live campaigns on hundreds of real leads revealed what actually breaks. Webhook deliveries stalled when voice data streams experienced packet loss, causing downstream CRM writes to freeze. Mid-lifecycle changes in n8n's data model required a structural rewrite of JSON arrays to prevent node failures. When a prospect hung up mid-sentence, the workflow had no graceful way to capture the partial conversational state. And the entire execution chain had no retry logic, meaning a single API error at 2 PM would kill a session that had been running since 9 AM.

All of that was fixable. The harder problem turned out to be something else entirely.

The Hardest Problem Was Not Technical

The webhook issues, the API migrations, the retry logic, all of that has a clear solution once you identify the failure point. The hardest problem to solve was how the AI introduces itself.

Early deployments revealed a pattern that no amount of infrastructure work could fix. Prospects would pick up the phone, engage for the first two or three exchanges, and then ask directly whether they were speaking to a person. Some sensed it earlier and asked immediately. When the AI hesitated, deflected, or gave a confusing answer, the call ended. When it disclosed upfront that it was an AI assistant calling on behalf of the company, a significant portion of prospects stayed on the line, answered the qualification questions, and some booked appointments.

The prompt became more important than any node in the workflow.

Getting the disclosure right required testing dozens of variations. The opening line needed to be clear about what the AI was without triggering an immediate hang-up. The tone needed to match the business using it. A dental clinic AI sounds different from a SaaS qualification agent. The pacing between sentences needed to feel natural even when the underlying model was processing at millisecond speed.

This is the part of the system that is hardest to show in a workflow diagram and easiest to underestimate. The orchestration layer can be technically perfect and the call will still fail if the first three seconds do not land correctly.

What Buyers Said: The Honest Version

Several small and medium businesses purchased the workflow in its earlier versions and ran it across live campaigns. Many got exactly what they came for: automated outbound volume, structured lead data, and time back from repetitive first-touch calls.

Others ran into friction. The AI at that stage had genuine limitations. It could lose context mid-conversation if a prospect went off-script. It sometimes misidentified the end of a sentence and interrupted. On calls with poor audio quality, speech recognition errors produced summaries that were partly unusable. These were not workflow failures. They were limitations of the underlying models and voice infrastructure available at the time.

What changed is the underlying technology. The LLMs powering Vapi today understand conversational context at a level that was not available when the first version shipped. Interruption handling is smoother. Voicemail detection is more reliable. The AI can now take a name, a date, and a time from a live conversation and write a confirmed appointment directly into a calendar or CRM field. That capability alone changes what the system can do for a service business that lives and dies by its booking rate.

The workflow architecture stayed consistent. What matured around it made the results meaningfully better.

Why n8n Instead of Native GHL Workflows or Vapi Campaigns

This is the question that comes up in almost every conversation about this system. GoHighLevel has a built-in workflow builder. Vapi launched native outbound campaigns. Why add n8n as an orchestration layer on top of both?

The answer is about what each platform was actually designed to do.

GoHighLevel's native workflows are built for marketing automation inside the GHL ecosystem. They move contacts through pipelines, trigger SMS and email sequences, handle appointment reminders, and manage internal notifications. That is what they are optimized for. What they cannot do is fetch a paginated contact list via a custom API call, check each record against an external filter condition, fire a voice call through Vapi, poll for a result every 35 seconds, parse a transcript, and then simultaneously write to a CRM field, send a Slack alert, and trigger an email nurture sequence. That entire chain requires an orchestration layer that GHL's workflow engine was never designed to provide.

Vapi's native campaign feature handles call scheduling and basic recipient management. But when a call ends, Vapi's responsibility stops. There is no native mechanism to map the AI summary and recording URL to a specific custom field in your CRM, advance the contact's pipeline stage, tag the record with a call outcome, and immediately fire a follow-up sequence. Managing concurrency limits across simultaneous campaigns and direct API calls also requires custom rate-limit logic that Vapi expects you to handle yourself.

n8n sits above both as the orchestration layer that neither platform can be on its own. It fetches leads from GHL using the current paginated API, builds a dynamic Vapi payload per contact, manages the polling loop with configurable retry logic, handles empty webhook responses and early call disconnects without halting execution, and routes the outcome to every downstream system in parallel. The entire operation runs on your own server with your own API keys, which means no platform markup on Vapi minutes or GHL usage and no third-party system holding your call data.

The practical result is a calling session that processes 300 contacts per day across a 9-hour window, without interruption, writing every result back to the CRM in real time.


Two Deployment Tracks for Different Operational Needs

The May 2026 stable release ships in two configurations.

Feature Standard Track (Google Sheets) Advanced Track (GoHighLevel CRM)
Data source Google Sheets lead list GHL contacts via paginated API
Trigger Manual, scheduled CRON, or row update Contact creation, tag applied, or pipeline stage change
Call monitoring n8n retry loops with counter limits Bidirectional webhook handshakes with status tags
Notifications Slack alerts and Sheet row updates GHL pipeline updates, internal notifications, and Slack
Post-call automation Google Sheet status marking Automated email and SMS nurture via Lead Conversion Funnel
Appointment booking Manual handoff to calendar Direct CRM field write with booking confirmation
API model Bring Your Own Key across all services Bring Your Own Key across all services
Acquisition Standard Agent on Gumroad Advanced GHL Agent on Gumroad

Standard Track: Google Sheets, Vapi, and Slack

The standard configuration is designed for teams that need automated voice outreach without a CRM integration. Google Sheets manages the prospect list. Vapi handles voice synthesis. Twilio routes the call. Slack receives structured alerts when a lead qualifies.

The workflow loads a Google Sheet and filters out records that have already been processed or contain invalid phone formats. For each valid lead it assembles a dynamic JSON payload containing the contact name, company context, and conversational targets, then dispatches it to Vapi's API. Vapi synthesizes the voice and connects through Twilio to dial the number.

A status-checking loop polls the call at structured intervals and maintains an attempt counter that forces an exit if Vapi encounters a network timeout. Once the call registers as completed, the workflow processes the AI summary, writes the transcript back to the Google Sheet, and sends a formatted notification to the Slack channel.

Advanced Track: GoHighLevel CRM with Multi-Channel Synchronization

For agencies and enterprise teams, the advanced configuration embeds the voice workflow directly into GoHighLevel, turning the AI agent into a synchronized sales representative that updates the CRM in real time and triggers follow-up sequences immediately after each call.

When a call ends, the conversational metadata including the AI summary, recording URL, detected outcome, and any appointment details map to specific custom fields in GoHighLevel. The contact's pipeline stage updates automatically. If the outcome qualifies as a warm lead, the Lead Conversion Funnel workflow fires immediately, orchestrating an automated email and SMS sequence calibrated to what was discussed on the call.


What Changed in May 2026 and Why It Took a Full Audit to Fix It

Going back to that Tuesday morning: a single Code node returning the wrong data shape was enough to silently corrupt every call result in the queue. No alert fired. The workflow showed a green status. The CRM was filling up with garbage. That kind of failure, the kind that does not announce itself, is the most dangerous in a system running hundreds of live calls per day.

Fixing it required going through every node in the workflow from scratch rather than patching the one visible symptom. What that audit revealed was a system that had accumulated technical debt across three separate dimensions at the same time.

n8n v2 Code node compatibility required rewriting the polling loop's return statement from a plain JavaScript object to a properly wrapped array of items. Without this correction, the If node downstream received empty data, defaulted to false, and exited the loop while the call was still in progress. The CRM write happened immediately on an incomplete transcript. The whole thing looked fine in the execution log.

GoHighLevel API migration moved the contact fetch from the deprecated GET /contacts endpoint to POST /contacts/search, which uses page-based pagination and accepts advanced filters including tags, date ranges, and custom fields directly in the request body. Both fetch nodes were updated and the authentication model was upgraded to support Private Integration Tokens alongside the legacy API key approach.

Error handling was rebuilt across the entire workflow. The original version had no retry logic on any HTTP node, meaning a single 500 error from Vapi or a rate limit from GoHighLevel would end the session with no recovery. Every HTTP node now carries automatic retry with configurable attempt counts, wait intervals between retries, and continue-on-failure behavior so that a temporary API disruption at any point in a multi-hour session does not kill the entire run.

Node version upgrades brought all 22 functional nodes to current maintained versions, including 6 HTTP Request nodes, 3 If nodes, and the Schedule Trigger.

Prompt layer rebuild reflects the step change in what the underlying AI can do today compared to what was available at launch. The agent now handles natural objections, maintains context across longer conversations, detects appointment intent mid-call, and writes confirmed booking details directly to the CRM record. The disclosure language was also refined across multiple industry templates so the AI introduces itself clearly without triggering an immediate hang-up.

Real Deployment Scenarios

  • Small businesses with online lead forms use the standard track to follow up on every submission within minutes of the form being submitted. The AI calls while the prospect is still at their desk, confirms the inquiry details, and either books a consultation or passes the lead to a human representative with a full transcript and outcome summary already in the CRM.
  • Digital agencies running local business campaigns use the system to replace the first layer of a call center operation for clients in service industries. The agent confirms contact details, offers to send a proposal, and routes interested prospects forward. The Google Sheet log gives the agency a clean deliverable after each session.
  • E-commerce brands recovering abandoned carts configure the advanced track to contact customers who left high-ticket items in checkout. The agent identifies whether the abandonment was a payment issue or a hesitation, delivers a discount code where appropriate, and logs the feedback.
  • SaaS companies qualifying new signups use the system to verify company size and product fit within hours of registration. Qualified opportunities move to the primary sales calendar automatically. Unqualified contacts receive a nurture sequence instead of a calendar invite.

What You Need to Deploy

The system requires a self-hosted or cloud n8n instance, a Vapi account, and a Twilio phone number. All workflows are delivered as pre-configured JSON files that import directly into n8n without any custom code required. The advanced track additionally requires a GoHighLevel account with API access enabled.

Standard Google Sheets Agent handles outbound calls with lead filtering, status polling, transcript capture, and Slack notifications through a 25-node workflow. Get the Standard Agent on Gumroad

Advanced GoHighLevel Agent handles full CRM synchronization, custom field mapping, paginated contact fetching, appointment booking, and native n8n v2 compatibility. Get the Advanced GHL Agent on Gumroad

Both repositories are open on GitHub with full README documentation covering node-by-node setup, credential configuration, and common troubleshooting scenarios. If this project helped you, a star on the repository goes a long way.

Discussion in the ATmosphere

Loading comments...