How to Automate Dispatch and Technician Scheduling for HVAC Companies
Learn to automate dispatch scheduling for HVAC companies with a no-code n8n workflow that assigns jobs by location, skill, and availability, then texts everyone.
Your dispatcher calls in sick and the whole day wobbles. That’s the real problem. When one person holds the board in their head — who’s closest, who can do a heat pump, who’s already double-booked at 2pm — you’ve built a business that runs on a single point of failure. And even on a good day, manual dispatch quietly bleeds money.
Here’s the math. A tech running 6 stops a day with sloppy routing wastes 45–90 minutes on avoidable drive time. Across 5 techs that’s roughly one full unbilled service call per truck per day — call it $150–250 in labor and lost capacity. Double-book a customer window and you eat a callback, a bad review, or an overtime hour. None of it shows up on a P&L line called “dispatch waste,” which is exactly why it never gets fixed.
You don’t need to rip out your field service software and buy a $400/month all-in-one to solve this. You can layer an automation on top of the tools you already run.
What manual dispatch is really costing you
Before you automate anything, name the leak. Three show up in almost every HVAC shop:
- Drive-time waste. Jobs get assigned by “who answers the radio,” not who’s nearest. Techs crisscross the service area all day.
- Skill mismatches. A new installer gets sent to a mini-split diagnostic he can’t finish, so you roll a second truck. Now one job costs two.
- The bottleneck human. Everything routes through one dispatcher. When they’re out, sick, or slammed, jobs sit and customers wait.
Automation fixes the first two by making assignment a rule instead of a guess. It fixes the third by making the rules the thing that runs the board, not a person’s memory.
Step 1: Structure your job data so a machine can read it
This is the step everyone skips, and it’s the whole game. An automation can’t assign a job it can’t understand. Right now your jobs probably live as free-text notes: “Mrs. Alvarez, no cool, call before arriving.” A computer can’t route that.
Every job needs four structured fields before any logic runs:
- Location — a full street address that geocodes to lat/long. Not “off Route 9.”
- Job type — a fixed dropdown: AC diagnostic, furnace repair, mini-split install, maintenance, no-heat emergency. Not free text.
- Required skill / cert — tied to job type. A mini-split install requires EPA 608 + install cert; a filter swap requires nothing special.
- Time window — a start and end (2-hour or 4-hour), not “afternoon.”
Then do the same for your techs. Build a simple techs table with these columns: name, phone, home base or current zone, skill tags, working hours, and a live availability flag. This can live in Airtable, Google Sheets, or your CRM’s custom fields. It doesn’t have to be fancy — it has to be consistent.
Spend a week enforcing dropdowns on intake and you’ll have clean data to automate against. Skip it and the automation will confidently send the wrong tech to the wrong place. Garbage in, dispatched.
If your intake is still messy, tighten that first — a clean client intake automation feeds everything downstream.
Step 2: Build the routing logic in n8n
Now the fun part. Here’s a working shape of the automation in n8n, which sits on top of your existing FSM or CRM instead of replacing it. Budget half a day to wire the happy path, then another day for fallbacks and testing.
Trigger: A new job hits “Ready to Dispatch” status in your CRM (or a new row lands in your jobs table). n8n watches for it via webhook if your system supports one, or a polling trigger every 2–5 minutes if it doesn’t.
The assignment sequence:
- Geocode the job address. A Google Maps node turns the address into coordinates. If it returns nothing or a low-confidence match, route to the “needs human” queue (see mistakes below) instead of guessing.
- Pull the candidate techs. Query your techs table for everyone who is (a) on shift right now and (b) carries the skill tag this job type requires. This one filter kills the two most expensive mistakes — after-hours misfires and skill mismatches.
- Calculate travel time to each candidate. Use the Google Maps Distance Matrix node from each tech’s current or next location to the job. You want drive time, not straight-line distance — a tech 4 miles away across a river is farther than one 8 miles down the highway. One Distance Matrix call covers all candidates at once, so a five-tech shop costs a fraction of a cent per dispatch.
- Check the time window fit. For each candidate, does adding this job break an existing commitment? Filter out anyone who’d be double-booked once you add drive time plus the job’s expected duration.
- Score and pick. Rank the survivors — usually shortest drive time wins, but you can weight it (e.g., prefer the tech already finishing nearby, or keep your senior tech open for emergencies). Assign the top one.
- Write the assignment back to the job record and flip the tech’s next-availability so the next job routes around it.
The core logic is a filter, a distance lookup, and a sort. That’s it. You’re not building self-driving cars — you’re encoding the three questions your best dispatcher asks in her head: Is he qualified? Is he free? Is he close?
This is the heart of technician routing automation for contractors — assignment by rule, not by radio.
Step 3: Notify the tech and the customer automatically
An assignment nobody sees is useless. The moment a job is assigned, fire two messages.
To the tech (SMS via Twilio, or push into their FSM app):
New job: Alvarez, 42 Oak St. AC diagnostic. Window 1–3pm. Customer prefers a call ahead. [tap for details]
To the customer (SMS):
Hi Maria — Rivera HVAC here. Your technician Dave is scheduled between 1–3pm today. He’ll text when he’s ~30 min out. Reply R to reschedule.
Two things this buys you immediately: fewer “where’s my tech” calls tying up the office, and a customer who feels handled. That confirmation text alone measurably cuts inbound status calls.
Then handle the thing that actually goes wrong every single day: jobs run long. Add a step so that when a tech marks a job complete (or overdue), n8n recalculates the ETA for the next customer and texts them the update automatically:
Update: Dave’s running about 40 minutes behind. New window is 3:40–4:15pm. Sorry for the wait — reply if that doesn’t work.
That single automated ETA update is the difference between a mildly annoyed customer and a one-star review. It’s also the message your dispatcher forgets to send when she’s drowning. Pair this with automated appointment reminders the day before and your no-show rate drops on top of it.
Step 4: Where a custom AI agent earns its keep
Rule-based routing handles about 80% of dispatch. The other 20% needs judgment, and that’s where a small AI layer helps.
- Messy inbound requests. A customer texts “furnace making a clicking noise and no heat since last night.” An AI step reads that, classifies it as a no-heat emergency furnace repair, tags the likely skill, and sets urgency — so your emergency doesn’t sit in a queue behind three maintenance visits.
- Reshuffling on chaos days. When two emergencies land and a tech calls out, an agent can propose a re-optimized board — “bump the 3pm maintenance to tomorrow, send Dave to the no-heat, pull Marcus off the install” — for a human to approve with one tap.
- Priority calls. Weighting a repeat commercial account or a warranty job over a routine tune-up.
Keep the AI narrow. Use it to classify and suggest, not to silently reassign your whole day. The rules do the routine work; the agent handles exceptions and hands you a decision instead of a mess.
Common mistakes that break this in the real world
Things that sink otherwise-good dispatch automations:
- No manual override. The owner needs a one-tap “reassign this” button. The day you remove human control is the day a customer’s mother-in-law’s furnace becomes an emergency the algorithm can’t see.
- Trusting stale locations. If a tech’s “current location” is really their 7am first stop, your drive-time math is wrong by noon. Update location on each job completion, or pull live GPS from the FSM app.
- Optimizing only for drive time. Pack routes too tight and one long job cascades delays through five customers. Build in buffer — assume jobs run 15–20% over quoted time.
- Silent failures. If the geocoder can’t find an address, the job must land in a “needs human” queue with an alert — never vanish. Add a fallback path for every step.
- Automating a broken process. If your intake data is inconsistent, automation makes the wrong decision faster. Fix the data first (Step 1). Always.
- Going all-in day one. Run the automation in “suggest only” mode for a week. Let it recommend assignments while your dispatcher still confirms. When it agrees with her 90% of the time, flip it live.
When this makes sense — and when it doesn’t
This pays off fast if you run 3 or more techs and dispatch 15+ jobs a day across a real service area. That’s where drive-time waste and the bottleneck-human problem cost you actual money every week.
If you’re a two-truck shop where the owner is the dispatcher and everyone knows the town cold, a full routing engine is overkill. Start smaller: missed-call text-back and automatic appointment reminders will give you more hours back per dollar first.
Your first concrete step this week isn’t building anything. It’s opening your last 30 jobs and checking: do they all have a clean address, a job-type dropdown, and a defined time window? If yes, you’re a few n8n nodes away from a dispatch board that runs itself. If no, that cleanup is the project — and it’s the highest-leverage day of work you’ll do this quarter.