AI Outbound Calling System

AI Outbound Calling System

AI outbound calling system for a real estate lead marketplace: texts and calls at the lead's local hour, retries, opt-out checks and a live A/B test.

Result974 leads in 19 days
Time spent112 hours
Timeline
Stack
  • n8n
  • Retell
  • PostgreSQL
  • RabbitMQ
  • GoHighLevel

The business

This is a real estate lead marketplace. Home sellers who need to sell fast leave a request through ads and the website. The marketplace qualifies each seller and passes the good ones to an investor. A lead counts as a win only when the seller is qualified and the phone number is live and picks up. The AI outbound calling system we built is the part that reaches those sellers by text and by voice.

The problem

Every lead is paid for before anyone calls it. If the first call lands at the wrong hour, or the number turns out to be a landline, the money is gone and the seller is cold. The marketplace felt this daily.

All contact lived inside GoHighLevel, and its built-in Voice AI placed the calls. It worked on paper. In practice the team ran into the same walls week after week:

  • SMS sends failed, and unsubscribes were handled unevenly.
  • Few calls were answered, and nobody could see why.
  • There was no control over how often a lead was contacted.
  • Retries were unreliable and the analytics were thin.
  • The Voice AI was closed, so a bad week could not be debugged.

The sharpest risk was invisible. Without a rule engine, nothing stopped a second call to someone who had just replied, or a call at 6 a.m. to a seller in another time zone. Calling an opted-out number twice is the kind of mistake that ends up with a lawyer, not in a report.

Diagram of lead contact handled entirely inside one CRM, with the built-in voice agent, SMS and retries and no view of contact frequency

Contact before the system: SMS, calls and retries inside one CRM, with no control over cadence and little reporting.

Why not stay with the CRM's voice agent

The founder did not want to guess. The comparison below is what pushed the contact logic out of the CRM, and the A/B test came from the same reasoning: measure both, then decide.

Built-in CRM voice agentWhat we built
When to call and textFixed behavior, no say in cadenceOur own scheduler decides, per lead, in lead local time
RetriesUnreliableAfter 1 hour, then 6 hours, moved into the calling window
Opt-outs and repliesHandled unevenlyChecked before every call, blocked and logged
Invalid numbersDialed anywayCarrier lookup first, so they cost no calls
ReportingThinEvery event in PostgreSQL, funnel and A/B report on top
Fixing a bad weekClosed systemOpen workflow with a state per lead

How the AI outbound calling system works

We moved contact out of the CRM into its own workflow in n8n. Intake is separate from processing, so a burst of new leads never slows the calls that are already due. The route has ten steps, and the last check before the phone rings is the one that matters most.

AI outbound calling system flow from the lead queue through number, opt-out and time zone checks, A/B split, SMS, call job, dispatcher, pre-call check and call, with a retry loop

The route of one lead. The pre-call check is the control point: no call is dialed until it passes.

  1. A new lead goes into a RabbitMQ queue and waits five minutes. The number is normalized to E.164.
  2. A carrier lookup checks that the number is a mobile, active, allows SMS and calls, and is not high risk. Invalid numbers are marked and cost no calls.
  3. The system checks whether this number ever unsubscribed. If so, the contact is blocked and logged.
  4. It finds the lead's time zone from the ZIP code.
  5. Leads alternate between variant A (Retell) and variant B (GoHighLevel).
  6. The lead gets an SMS from a dedicated number, and the event is recorded.
  7. A call job is created for the lead's local time. Calls go out only between 08:00 and 21:00 there.
  8. A dispatcher picks up due jobs every minute. At most 18 calls run at once, and a database lock keeps two runs from taking the same job.
  9. Right before dialing, the system checks again for a reply, an opt-out or an earlier answered call. Any of them stops the job.
  10. Retell places the call, the result is parsed and written to the CRM. If nobody answers, a retry follows after one hour and then after six hours, moved into the daytime window.
Call queue screen with jobs grouped by status, attempt bars, lead local times and a counter showing 12 of 18 call slots in use

Call queue. Jobs come from the database, and the slot counter shows the cap of 18. Redrawn with demo data.

Timeline of one lead with SMS, two unanswered calls, a reply, a stopped third call and a callback transferred to an investor

One lead from first touch to investor. The third call never dialed because the lead had already replied. Redrawn with demo data.

Replies, callbacks and the investor handoff

Leads do not follow the script. They reply to the text, call the number back, or answer on the second try. Inbound SMS and calls go into the same events table as everything else, so the next decision always sees the full history.

When a lead calls back, a separate callback agent answers. If the seller qualifies, the call is transferred live to an investor. A repeat call is scheduled for sellers who asked to be reached later. The same Retell setup also runs an inbound voice agent for the website.

The hard parts

Never calling twice

The dispatcher runs every minute, so two runs can overlap. A database lock stops them from taking the same job, and the cap of 18 simultaneous calls keeps the load predictable. The pre-call check closes the remaining gap: if the lead replied, called in, unsubscribed or already picked up, the job ends without dialing.

Calling at a sane hour

Leads come from many time zones and calls are allowed only in the daytime. Each job carries the lead's local time. A retry that would land at 21:25 moves to 08:00 the next morning instead of firing on a fixed delay.

Comparing two systems fairly

To choose with data, we split leads between Retell and GoHighLevel and measured both. The first version of the comparison math was off. We fixed the calculations in September 2026, and every number below uses the corrected version.

Numbers and SMS errors

Failed sends were one of the original complaints. We moved telephony and number management to Telnyx, so the team now controls the sender numbers and sees delivery per message.

Result

The system has run in daily production since summer 2026. In about 19 days of September 2026 it handled 974 leads, 965 of them valid, and 955 received a first contact. 535 were reached (55.44%). It placed 1,858 calls, 1.91 per lead, and 323 were answered (17.38%). It sent 957 SMS messages, 912 delivered (95.30%), and 31.73% got a reply.

Funnel from 974 leads to 535 reached, call and SMS totals and a comparison table of variants A and B

Funnel and variant comparison, counted from the events table. Redrawn with demo data.

The A/B test is the more useful result. Today GoHighLevel answers better, and we say so. The old setup gave the team no such comparison at all.

Bar charts of call answer rate and SMS reply rate for variants A (Retell) and B (GoHighLevel): 14.21% and 20.61% for calls, 30.08% and 33.4% for SMS

Answer rates by variant, September 2026, about 19 days, corrected calculations.

BeforeAfter
Calling rulesOut of the team's handsWindow, cap and cadence set by the team
Invalid numbersDialed anywayFiltered by a carrier lookup
Replies and opt-outsHandled unevenlyChecked before every call
RetriesUnreliable1 hour, then 6 hours, in the daytime window
Voice setupOne closed agentTwo variants compared on the same leads
ReportingThinFunnel, calls, SMS and A/B from one events table

The marketplace now decides where traffic goes from its own numbers instead of a vendor's promise, and it can switch the voice provider without rebuilding the route.

Our part

We built the orchestration in n8n, the queue, the event model, the call scheduler, the Retell voice agents for outbound and callback calls, the Telnyx number setup and the analytics, and we run them day to day. The marketplace backend belongs to another developer, and the client's manager owns the strategy for raising the contact rate. We started in June 2026.

The same approach to calls shows up in the AI phone dispatcher we built for a home services company. For the engineering side, read why a queue makes webhook automation reliable and how to model CRM funnel events.

Running a process like this by hand?

Tell us what your team repeats every week. We reply within one business day with a plan and a price.

See similar projects