Guides
A step-by-step guide to building a home services AI agent in Thoughtly that answers every call, qualifies service type and urgency, routes emergencies to dispatch, books appointments, and follows up with SMS.
Last updated
Home services contractors — HVAC, plumbing, roofing, electrical, and similar trades — lose revenue every time a call goes unanswered. A missed call from a homeowner with a burst pipe or a broken AC unit is a lost job, often within minutes. Thoughtly's AI voiceAI voiceAn artificially generated, natural-sounding voice produced by a TTS model. Thoughtly supports a library of AI voices and brand-specific cloning. agents solve this by answering every inbound call, qualifying the service need, routing emergencies to your dispatch line, booking appointments, and following up with SMS — all without adding headcount.
This guide walks through building a home services AI agent in Thoughtly from scratch: greeting callers, capturing service type and urgency, scheduling appointments, transferring emergency calls, and automating post-call follow-up. You'll learn the exact node structure, variables, outcomes, and automations to deploy a production-ready agent.
Whether you run a single-location plumbing company or a multi-branch HVAC franchise, the same agent architecture applies. The examples below use real Thoughtly product mechanics — no invented features.
Cal.com, Calendly, or Acuity) for appointment bookingHubSpot, Salesforce, GoHighLevel, or Pipedrive) for contact syncingBefore you start, map out your call flow on paper. Know which service types you offer, which constitute emergencies, what your service hours are, and what information you need from each caller (name, address, phone, service type, urgency, preferred time).
In Thoughtly, navigate to Agents and create a new voice agentVoice agentAn autonomous, conversational interface that interacts with humans over the phone — answering, qualifying, and routing calls without human staffing.. Name it something recognizable — for example, "Home Services Intake Agent." In the Agent Builder, start with the Start node.
The Start node is the entry point for every call. For a home services agent, use a Message speak node (not Prompt) so the greeting is identical every time. Keep it tight:
Thank you for calling Acme Home Services. How can I help you today?Use the Company name field in agent settings to set your business name — this powers branded callingBranded callingDisplaying a verified business name, logo, or call reason on the recipient’s phone so legitimate calls are less likely to be ignored or flagged as spam. and caller ID display. Set it to your actual business name (for example, "Acme Home Services").
In the Start node's speech settings, enable Spell Numbers for any phone numbers or addresses the agent reads back. This prevents the TTSText-to-Speech (TTS)The system that turns the agent's generated text into spoken audio — the voice the caller actually hears. engine from garbling ZIP codes or street numbers.
After the greeting, connect a Speak node in Prompt mode. This node asks the caller what they need and collects key information. The prompt should be conversational but structured:
You are an intake agent for a home services company. Ask the caller what service they need. Collect the following: service type (HVAC, plumbing, electrical, roofing, or other), their address, and how urgent the situation is. If the caller mentions water leaking, gas smell, no heat in winter, no AC in extreme heat, or any safety concern, flag this as an emergency. Be concise and friendly. Do not quote prices or promise specific arrival times.Define variables on this node to extract structured data for downstream branching:
service_type: Text. Extract the service category the caller describes (HVAC, plumbing, electrical, roofing, other).service_address: Text. Extract the caller's address. Normalize to a single line.is_emergency: Boolean. Return true if the caller describes a safety risk, water damage, gas smell, no heat in freezing weather, or no AC in extreme heat. Otherwise false.caller_name: Text. Extract the caller's first and last name if provided.preferred_time: Text. Extract the caller's preferred appointment window if mentioned.Set each variableVariableA named value the voice agent stores during a conversation — caller name, intent, qualifying answers — and uses to drive routing and post-call actions.'s Source to Current speak node so extraction pulls from the most recent caller reply, not the full conversation history. This reduces the chance of stale or mixed values.
On the qualification Speak node, add rule-based outcomes (not prompt-based) for deterministic routing. Rule-based outcomes evaluate variables top-to-bottom and take the first match — critical for safety-sensitive emergency dispatch.
Create three outcomes in this order:
is_emergency == true → routes to a Transfer node connected to your dispatch line.service_type is not empty → routes to the appointment scheduling node.The order matters. If the Else outcome were first, it would always match and the emergency check would never run. Always place the most specific rules above general ones.
This pattern — Variables → Rule-based Outcomes → deterministic routing — is the recommended approach for any safety-adjacent decision. The Thoughtly docs explicitly warn against using prompt-based outcomes for compliance-critical or safety-critical paths.
When the emergency outcome fires, route to a Transfer node configured as a Phone Router transfer. Set the destination to your dispatch line — the number a human dispatcher or on-call technician answers.
In the Transfer node's optional Message field, add a brief pre-transfer message so the caller knows what's happening:
It sounds like this is an emergency. I'm connecting you to our dispatch team right now. Please stay on the line.The transfer occurs immediately after the message. Phone numbers are validated in real-time using country-aware formatting rules, so you don't need to worry about formatting edge cases in the destination field.
Enable Early Summaries on this Transfer node. Early summaries generate a concise context summary before the transfer completes, so your dispatch team receives caller context (service type, address, emergency description) the moment they pick up — not after the call ends.
For non-emergency calls, route to a Speak node in Prompt mode that handles appointment scheduling. This node confirms the service type, offers available times, and books the appointment.
If you've connected a scheduling integration (Cal.com, Calendly, or Acuity), add a scheduling Action to this Speak node. The action checks availability and books directly during the call.
The recommended pattern from Thoughtly docs is: Speak node collects preferred time → Action schedules appointment → rule-based outcomes check booking_status → confirmed or retry.
booking_status == "confirmed": speak a confirmation message, then send an SMS with the appointment details, then End.You are a scheduling assistant for a home services company. The caller needs {service_type} service at {service_address}. Offer the earliest available appointment. If the caller accepts, book it. If no times are available today, offer tomorrow's first available slot. Confirm the booking details before ending the call.Use the bolt icon in the prompt editor to insert variable chips like service_type and service_address. Variables are extracted earlier in the conversation and available for reference in downstream nodes.
If you don't use a scheduling integration, the agent can still collect preferred times and write them to your CRMCRMThe system of record for leads, contacts, deals, and activity. Thoughtly reads from and writes to your CRM continuously. or a webhookWebhookAn event-based integration that sends data from one system to another when something happens, such as a form submission, booked appointment, or completed call. as a lead note. Your dispatch team follows up to confirm.
After a successful booking (or even for non-booked calls), add a Send SMS action to the scheduling or end node. This sends the caller a text with their appointment details, service type, and a contact number.
Hi {caller_name}, your {service_type} appointment with Acme Home Services is confirmed for {preferred_time}. We'll text you when the technician is on the way. Call us at 555-0100 if you need to reschedule.SMS messages can be sent during calls or as part of automation workflows using the Send SMS action. For post-call SMS, use an Automation with the On Call Completed triggerTriggerThe event or condition that starts an automated workflow, such as a new lead, missed call, CRM status change, calendar booking, or completed call. instead of a mid-call action.
Create at least two End nodes — one for the happy pathHappy pathThe ideal conversation flow where every input matches expectations and the agent reaches the intended outcome with no detours. (appointment booked) and one for fallbackFallbackA safe backup path used when the caller says something unexpected, an integration fails, or the agent cannot confidently complete the intended step. (caller not interested, could not book, or service areaService areaThe geography where a business can serve a prospect. Service-area checks prevent routing or booking leads a team cannot actually handle. not covered).
Happy path End node message:
You're all set. We'll see you at your appointment time. If you have any questions before then, give us a call. Thanks for choosing Acme Home Services. Have a great day!Fallback End node message:
I wasn't able to book an appointment right now, but I'll pass your information to our team and someone will reach out shortly. Thanks for calling Acme Home Services.Each End node closes the conversation gracefully and hands control back to any downstream automations. The End node's message is spoken verbatim, so review it for accuracy.
After the call ends, a post-call automation handles CRM updates, dispatch notifications, and analytics. Create an Automation with the On Call Completed trigger, scoped to this agent.
The On Call Completed trigger fires after a call ends and provides rich call data: durations, outcomes, variables captured, action flags, transfers, and voicemail detectionVoicemail detectionVoicemail detection is the ability to identify when a call reaches a voicemail greeting instead of a live person, then trigger the right message, callback, or alternate-channel follow-up.. Use this to build your post-call workflowWorkflowAn automated, multi-step process — usually triggered by an event (form fill, new lead) and orchestrating one or more voice / SMS / email actions..
A typical home services post-call automation:
If you use HubSpot, Salesforce, or GoHighLevel, replace the webhook step with the native CRM integration step. Map fields from the trigger payload (service_type, service_address, is_emergency, booking_status) directly to CRM properties.
Create a Genius knowledge baseKnowledge baseA structured source of business information, FAQs, policies, product details, or procedures that an AI agent can use to answer accurately. with Q&A entries covering your service area, service types, pricing ranges, business hours, and common FAQs. Attach it to the agent via Settings → Genius tab. This lets the agent answer questions like "Do you work on weekends?" or "What areas do you serve?" without scripting every possible question.
Keep Genius content in strict Q&A format for faster retrieval and fewer hallucinations:
Q: What areas do you serve?
A: We serve the greater Austin metro area, including Round Rock, Cedar Park, Pflugerville, and Georgetown.
Q: Do you offer emergency service?
A: Yes, we offer 24/7 emergency service for plumbing and HVAC. Call our main number and select the emergency option.
Q: What are your business hours?
A: Our normal business hours are Monday through Friday, 7 AM to 6 PM. Emergency service is available 24/7.Review Genius content regularly. The docs caution that outdated scheduling data or stale information in Genius can confuse the agent — especially time-sensitive details like seasonal hours or service area changes.
Thoughtly provides two testing tools: Test Agent (text chat) for fast logic verification and Call Me (real call) for voice and transfer testing. Test in this order:
Use the Test Agent's sample metadata feature to inject test contact data (name, phone, address) so you can verify variable interpolation without making real calls.
Track these metrics after deploying your home services agent:
is_emergency extraction instructions if needed.Use Thoughtly's Search Calls feature to review call transcripts, filter by outcome, and spot patterns. Regular review — weekly at minimum — helps you catch and fix issues before they cost jobs.
Yes. Define service_type as a Text variable and let the prompt capture whatever the caller describes. The agent can route differently based on the extracted value using rule-based outcomes — for example, plumbing emergencies go to one dispatch line, HVAC emergencies to another.
Add a rule-based outcome that checks the service_address variable against your service area list. If the address doesn't match, route to an End node that politely explains you don't serve that area. You can also store your service area in a Genius knowledge base and have the agent check during the conversation.
Yes. Deploy the agent on your inbound number and it answers 24/7. For after-hours calls, you can adjust the prompt to inform callers of your business hours, offer emergency-only dispatch, and book non-urgent appointments for the next business day. See the Thoughtly after-hours guide for a detailed walkthrough.
The is_emergency variable uses AI extraction with explicit instructions. You define what counts as an emergency for your business — gas leaks, water damage, no heat in freezing weather, no AC in extreme heat, electrical sparking, etc. The extraction instructions tell the model to return true only when these conditions are present. For extra safety, use rule-based outcomes so the routing is deterministic once the variable is set.
Yes, but build a separate agent for outbound campaigns with a different prompt and flow. Outbound agents need a reason for calling (set in the Reason for calling field) and should reference the contact's history. Trigger outbound calls using Automations — for example, a recurring schedule that calls back quotes that weren't booked, or a webhook from your CRM when a lead is assigned.
Thoughtly Agent Builder documentation — Node types and conversation flowConversation flowThe designed path an AI agent follows through greeting, intent capture, qualification, routing, objections, fallback, and next-step confirmation.
Thoughtly Variables documentation — Data extraction and validation
Thoughtly Outcomes documentation — Rule-based vs prompt-based branching
Thoughtly Actions documentation — Mid-call integrations and scheduling
Thoughtly Automations documentation — Post-call workflows and triggers
Thoughtly Genius documentation — Knowledge base setup and Q&A formatting
Thoughtly — Home Services solution page
Thoughtly blog — How to Handle After-Hours Calls with AI Voice Agents
Thoughtly blog — How to Build an Appointment-Setting AI Agent
Thoughtly blog — AI Agents for Home Services Missed-Call RecoveryMissed-call recoveryAutomatically calling or texting back prospects who reached the business but did not connect with a human, so high-intent demand does not disappear into voicemail.
Thoughtly blog — How to Build an AI ReceptionistAI receptionistA voice agent configured to answer inbound calls, capture intent, route callers, book appointments, and handle front-desk tasks. with Thoughtly
Thoughtly blog — How to Use SMS After a Missed Call Without Annoying Prospects