Case study
I build voice AI agents that make real time triage and dispatch decisions under ambiguity, live in production for two plumbing companies.
The same voice AI system is live for two plumbing companies.
At Callahan Pipe & Drain, a Chicago plumbing company, the agent is embedded on the production website as a one click call button. It handles inbound service requests, emergency triage, and scheduling, then routes to human dispatch when needed. It runs on Vapi with FastAPI backend integrations for calendar and CRM.
At ClearFlow Plumbing, the agent handles emergency dispatch and service scheduling: real time emergency classification (burst pipes, gas leaks, floods), automatic technician dispatch, a dynamic pricing engine with upfront estimates, customer service history integration, and payment processing integration.
Problem
Plumbing companies field urgent calls where the right response depends on what the caller describes: a burst pipe, a gas leak, a flood, or a routine service request. The agent takes the call, works out how urgent it is, and either books the job or brings in a human dispatcher.
- TODO(otito): What went wrong before the agent existed (missed calls, slow dispatch, after hours coverage)?
Constraints
It is a live voice agent, so it has to respond in real time, on a phone line or from a one click call button on the customer's production website.
- TODO(otito): Latency budget and how you kept responses fast
- TODO(otito): Rules from the business (which emergencies must reach a human, pricing rules)
- TODO(otito): Any telephony, cost, or compliance limits
Architecture
Boxes come from the integrations named on this site: Vapi, FastAPI, calendar, CRM, pricing, payments, and human dispatch.
- TODO(otito): Confirm the diagram matches production, and add the missing pieces (technician dispatch, service history, hosting, logging)
- TODO(otito): Tool and integration list (which CRM, payments provider, and scheduling tool at each company)
Key decisions
The agent hands off to a human dispatcher when needed instead of trying to handle every call itself.
- TODO(otito): What triage categories exist and how emergencies are classified
- TODO(otito): Why Vapi and FastAPI, and what you rejected
- TODO(otito): How the agent decides to hand off to a human
Evaluation
- TODO(otito): How you tested triage accuracy before and after launch
- TODO(otito): Share of calls handled without a human, and how it was measured
What broke and how I fixed it
- TODO(otito): A real failure case, its root cause, and the fix
Outcome
The system is live for two plumbing companies, Callahan Pipe & Drain and ClearFlow Plumbing.
A customer told me it saves them roughly 6 hours a week. This is their estimate, not a figure I measured.
- TODO(otito): Which customer said the 6 hours a week (or can you get a short quote and permission to name them)? Was it about their own business only?
- TODO(otito): Call volume handled and over what period
- TODO(otito): Any result the owners would confirm (customer satisfaction, leads, booked jobs, missed calls, response time)
- TODO(otito): About 50 customers: is that the Abstraction studio overall or this voice agent, and can it be stated on this page?
- TODO(otito): What the agent does beyond answering calls, for Key decisions
Hear it handle a real call
Both agents are live. Call one and listen to it triage a request.
Callahan Pipe & Drain
Call the live agent from the one click call button embedded on the production site.
ClearFlow Plumbing
Call the live demo line and hear it triage your call in real time.