System Overview

The Billing Dialer is an AI-powered outreach system that manages the full 180-day payment lifecycle across 5 client segments. It uses automated voice calls (Retell AI agent "Grace"), templated SMS (HeyMarket), and live agent transfers (Talkdesk) to guide clients from a missed payment through resolution — or, when necessary, through suspension and cancellation.

Integration Architecture
Four external services work together to drive the full outreach lifecycle
DatabricksDialflowRetell/HeyMarketTalkdesk

Retell AI

Voice Agent

AI voice agent Grace handles outbound calls, voicemail detection, and live agent transfers

HeyMarket

SMS Platform

Templated SMS with dynamic variable injection — separate inboxes for billing vs. resurrection

Dialflow

Agent Availability

Real-time agent availability API — gates batch release until enough agents are free

Databricks

Data Warehouse

Source of eligible clients via SQL query; receives call history write-back on campaign stop

Workflow & Tech Stack
A step-by-step look at how the system operates daily — and what technology powers each stage

Daily Workflow

Queue Load from DatabricksDatabricks SQL Connector

A configurable SQL query runs against the Databricks warehouse to pull eligible clients. Each row includes client ID, name, phone, segment, days past due, and ring group.

Uses @databricks/sql with a Personal Access Token. The query itself is stored in the system settings so it can be updated without a deploy.

Cadence Resolution & Queue InsertPrisma ORM → Neon Postgres

Each row is matched to its cadence day and segment config. The system resolves SMS templates, voicemail prompts, live-call prompts, transfer numbers, and action type (SMS, Call, or Both).

Rows are enriched with per-segment transfer numbers (billing vs. resurrection) and inserted into Neon Postgres via Prisma in batches of 100.

Revalidation LoopDatabricks SQL (periodic)

While the campaign is running, the same queue query is re-executed periodically. The returned client IDs are cross-referenced against the stored queue — any queued client not in the result is marked INELIGIBLE and skipped.

Runs on a configurable interval (default 30 minutes). Prevents calling clients who resolved their balance mid-campaign.

Batch Release & Availability CheckOrchestrator + Dialflow API

The orchestrator groups queued items by ring group, checks live-agent availability via the Dialflow API, and releases batches when enough agents are available.

Batch size and release threshold are configurable per campaign. If no agents are available, the loop polls every 5 seconds until availability opens up.

AI Voice Calls via RetellRetell AI API (v2)

Each batch item triggers an outbound call through Retell AI. The AI agent "Grace" receives dynamic variables — client name, past-due amount, cadence-specific prompts, and the correct transfer number.

POST /v2/create-phone-call with override_agent_id and retell_llm_dynamic_variables. Supports live-call prompts, voicemail prompts, and warm transfers.

Webhook ResolutionRetell Webhooks → Next.js API

When a call ends, Retell fires a webhook. The system maps the disconnection reason to an outcome: answered, voicemail, transferred, no-answer, or failed.

call_ended fires immediately; call_analyzed provides voicemail vs. answered disambiguation. Outcomes update queue item status and campaign counters.

SMS Delivery via HeyMarketHeyMarket API (v1)

SMS-only cadence items fire at a randomized time (10 AM – 1 PM). "Both" items send a follow-up SMS after a voicemail or no-answer call outcome.

POST /v1/message/send with dynamic templates. Resurrection-phase messages route to a separate HeyMarket inbox for specialized agent handling.

Live Transfer to TalkdeskPSTN Transfer via Retell → Talkdesk

When a live client wants to speak with an agent, the Retell voice agent initiates a warm transfer to the Talkdesk phone number configured for that segment.

Transfer numbers are per-segment (billing vs. resurrection). The webhook logs the transfer and marks the queue item as TRANSFERRED.

Campaign Stop & History FlushDatabricks SQL INSERT

When the campaign stops (manually or at end-of-day), all call outcomes are written back to Databricks for analytics and reporting.

INSERT INTO analytics.billing.dialer_call_history with full outcome data. Queue items are then cleaned up from Postgres.

Tech Stack Breakdown

Next.js 16

Framework

  • App Router with server & client components
  • API routes for campaign control and webhooks
  • Standalone output for container deployment

Neon Postgres + Prisma

Database

  • Serverless Postgres via @prisma/adapter-neon
  • Models: Campaign, QueueItem, Cadence, Schedule, Config
  • Batch inserts (100 at a time) for queue loading

Databricks SQL

Data Warehouse

  • Daily queue pull via configurable SQL query
  • Periodic revalidation for eligibility changes
  • History write-back for analytics on campaign stop

Retell AI

Voice Agent

  • AI agent "Grace" with dynamic LLM variables
  • Voicemail detection & live-call prompts per cadence day
  • Webhook-driven outcome resolution (call_ended / call_analyzed)

HeyMarket

SMS Platform

  • Template-driven SMS with dynamic variable injection
  • Separate billing and resurrection inboxes
  • Randomized send window (10 AM – 1 PM) for SMS-only items

Talkdesk

Contact Center

  • Per-segment transfer numbers for live agent routing
  • Billing ring group pre-suspension, resurrection post
  • Warm transfer initiated by Retell voice agent

Dialflow

Agent Availability

  • Real-time agent availability checks per ring group
  • Gates batch release — calls only fire when agents are ready
  • Polled every 5s during the release loop

In-Process Orchestrator

Batch Engine

  • Async release loop with configurable batch size
  • 2-minute safety timeout per batch
  • SMS scheduler with randomized daily send time

TypeScript + Zod + Pino

DX & Reliability

  • End-to-end type safety with TypeScript 5
  • Runtime validation with Zod on API inputs
  • Structured logging with Pino for observability
Client Segments
Each segment has its own 180-day cadence tailored to the payment context and suspension timeline
SegmentPast DueSuspensionCancellationTouchpointsNotes
RED InitialDay 1Day 60Day 180~50Standard billing cadence for initial RED payments
RED RecurringDay 1Day 60Day 180~50Same cadence as RED Initial — same billing segment
Reso InitialDay 1Day 90Day 180~50Resolution plan first payment — 30 extra days before suspension
Reso RecurringDay 14Day 90Day 180~5014-day grace period built into the cadence
Reso ServicingDay 31Day 122Day 180~50Monterey Financial. Longer grace and billing window.
180-Day Cadence Lifecycle
Every client follows a phased journey from missed payment through potential cancellation. The tone shifts from billing urgency to empathetic resurrection after suspension.

RED Initial / Recurring

Billing Escalation
Resurrection
Pre-Cancellation
01260150180
Billing tone
Resurrection tone
Milestones

Day 0

Payment missed — friendly SMS

Day 1 — Past Due

Account is past due — soft intro outreach begins

Soft Intro

Friendly check-ins, no amounts cited

Billing Escalation

Past-due amounts, urgency increasing, suspension warnings

Day 60 — Suspension

Account suspended — work paused

Resurrection

"We're still here" — empathetic re-engagement, ready when you are

Pre-Cancellation

Cancellation risk warnings, urgent final outreach

Day 180 — Cancellation

Case cancelled — final communication

The Billing → Resurrection Shift
Suspension marks a clear tonal pivot in how we communicate with clients. Messaging, call routing, and SMS inboxes all change.

Pre-Suspension: Billing Tone

Escalating urgency. Past-due amounts cited. Account risk warnings. Goal is to collect before suspension.

Soft Intro (Days 1-10)

Just a friendly reminder — we still have a payment that needs your attention.

Past Due (Days 12-30)

Your overdue payment is holding things up. We want to help get this resolved and keep things moving.

Pre-Suspension (Days 31+)

Your account is at risk of suspension. Suspension will halt our work on your resolution options.

Post-Suspension: Resurrection Tone

Empathetic re-engagement. “We're still here.” No pressure — ready when they are. Cancellation risk introduced later.

Re-engagement (Post-Suspension)

Your account is suspended but we're still here for you. When you're ready, give us a call or text us.

Direct (Mid Re-engagement)

We're still here and want to help you move toward resolution. Give us a call — let's talk.

Pre-Cancellation (Day 150+)

We don't want to see your case cancelled. Please call us so we can discuss keeping your resolution options alive.

Routing Changes at Suspension

Call transfers route to the resurrection ring group and transfer number instead of the standard billing line

SMS replies route to a dedicated resurrection inbox in HeyMarket for specialized agent handling

Touchpoint Action Types
Each cadence step uses one of three action types

SMS

Sends a templated SMS via HeyMarket with dynamic variables (client name, past-due amount, days past due, payment link).

Call

AI voice agent "Grace" calls the client via Retell. If answered, uses the live-call prompt. If voicemail, leaves a contextual message. Can transfer to a live agent.

Both

Sends SMS and places a call on the same cadence day. Used for milestones and high-priority touchpoints to maximize reach.