Read → Classify → Check History → Prioritise → Route

Maintenance Triage and Dispatch

Reads each incoming maintenance request, classifies the right trade, checks the unit's history for repeat issues, sets priority against your rules, and routes the ticket to the correct queue ready for dispatch.

The Problem

The wrong tech showed up. Twice.

A request comes in: "Water on the bathroom floor." Your coordinator reads it, calls it plumbing, sets it as medium priority. The plumber shows up - it's actually a leaking AC condensate line. Wrong trade. Rescheduled. The resident calls twice. Two wasted visits.

What Changes

The right tech, the first time.

The agent reads the request, checks the unit's maintenance history, and finds that the AC condensate line was flagged six months ago. It assigns the ticket to HVAC instead of plumbing and sets priority to high because of potential water damage. The right tech shows up the first time.

Humans stay in control: Your coordinator approves every dispatch and overrides any call the agent gets wrong. The agent handles the reading, the trade classification, the history lookup, and the priority rules. It removes the guesswork on routing, not the decision to send.

HOW THE AGENT WORKS

TRIGGERLLMAPIDECISIONACTIONWAIT
TRIGGERRequest ArrivesWebhook from portal, SMS, email, or phone-log entry
LLMRead & ClassifyLLM reads request → trade, symptom, location
APIPull Unit HistoryQuery PMS for past tickets on this unit/asset
LLMMatch Repeat IssueCheck whether this symptom has appeared before
DECISIONSafety / Emergency?
LLMSet PriorityApply priority rules - damage risk, habitability
APIFind Queue / TechMap trade to the right queue or assigned tech
DECISIONDetails Complete?
ACTIONRoute TicketCreate routed work order, flag for coordinator
ACTIONAlert CoordinatorHigh-priority or emergency → immediate notification
The agent uses the same information your coordinator would use - it just checks the history faster and applies trade classification rules consistently. Your coordinator still reviews and approves the dispatch. The agent removes the guesswork, not the oversight.

HOW TO BUILD IT

Three levels of depth. Pick the one that matches where you are.

For the ops person who needs to understand what's involved and brief their team.

Your IntakePortal, SMS, email, phone log
The AgentWorkflow engine + LLM
Your PMSUnit history, work orders, queues

WHAT YOUR TEAM PROVIDES ONCE

  • Your trade taxonomy - the categories and sub-categories work gets sorted into
  • Priority rules - what counts as emergency, high, medium, low, and why
  • Routing map - which trade goes to which queue, vendor, or in-house tech
  • Required details per category - what a complete ticket needs before dispatch
  • Escalation rules - when the coordinator gets pinged instead of auto-routed
What happens day-to-day: Requests arrive the way they always do. The agent reads each one, classifies the trade, checks the unit's history, sets priority, and routes it. Your coordinator opens a queue of correctly sorted tickets every morning instead of a pile of raw text to triage by hand.

For the IT person or technical lead who needs to scope the integration.

INQUIRY SOURCES

Resident portal
SMS / email inbox
Phone-log entry

WORKFLOW ENGINE (N8N)

Trigger
LLM - Classify trade
PMS API - Unit history
LLM - Match + prioritise
Rules - Routing map
PMS API - Create WO
Notify coordinator

CONNECTS TO

PMS (Yardi / AppFolio / RealPage)Read: unit history, queues. Write: routed work order
Intake channels (portal / SMS / email)Read: incoming requests
Notifications (Slack / email / SMS)Alert coordinator on emergency or low-confidence calls
CMMS (optional - e.g. Property Meld)Optional - sync ticket status and dispatch
WITHOUT PMS API

Agent classifies and prioritises from the request text alone and posts the routed ticket to a shared queue or sheet. No history lookup, so repeat-issue matching is skipped. Still removes the manual triage step.

WITH PMS API

Agent reads live unit history and writes the routed work order straight back. Classification uses real repeat-issue data. Best experience.

For the person who wants to build this agent step by step. Each node below maps to an n8n workflow node.

TRIGGERNode 1
Trigger - Webhook / Email / SMS
Webhook from portal, OR IMAP on the maintenance inbox, OR Twilio inbound SMS. Normalise all three into one payload.
Output: { unit_id, resident_name, channel, raw_message, photos, timestamp }
LLMNode 2
LLM - Classify Trade & Symptom
OpenAI GPT-4 or Anthropic Claude. Classifies the request into your trade taxonomy and extracts the symptom and location.
Output: { trade, sub_category, symptom, location, access_notes, confidence }
You are an assistant that reads property maintenance requests and classifies them.

Read the request below and return:
- trade: one of [plumbing, hvac, electrical, appliance, general, pest, life_safety]
- sub_category: a short specific label (e.g. "water leak", "no cooling", "outlet dead")
- symptom: what the resident is actually reporting, in a few words
- location: room or area in the unit
- active_damage: true if water/electrical/safety damage may be ongoing, else false
- access_notes: any entry or pet instructions mentioned
- confidence: high / medium / low - how sure you are of the trade

If the trade is ambiguous between two options, set confidence to low and name both in sub_category.
Respond ONLY with valid JSON. No explanation.

--- REQUEST ---
{raw_message}
INPUT
"There's water on the bathroom floor near the toilet, been there since this morning. It's spreading toward the hallway. You can come anytime, no pets."
OUTPUT
{
  "trade": "plumbing",
  "sub_category": "water leak - possible toilet or condensate line",
  "symptom": "water pooling on bathroom floor, spreading",
  "location": "bathroom",
  "active_damage": true,
  "access_notes": "anytime, no pets",
  "confidence": "low"
}
APINode 3
HTTP Request - Pull Unit History
GET request to your PMS/CMMS API for past work orders on this unit. Fallback: read from a maintenance-history sheet if no API.
Output: Array of past tickets: [{ date, trade, sub_category, resolution, recurring_flag }]
DECISIONNode 4
Condition - Emergency or Repeat?
IF active_damage = true OR trade = life_safety → priority = emergency, alert coordinator now. ELSE IF symptom matches a past ticket → raise priority one level and attach history.
Output: Branch: EMERGENCY (alert + route) or NORMAL (continue to priority rules)
LLMNode 5
LLM - Set Priority & Resolve Trade
Applies your priority rules and uses unit history to resolve a low-confidence trade call (e.g. recurring AC condensate line → HVAC, not plumbing).
Output: { final_trade, priority, reason, history_note }
You are a maintenance dispatch assistant. Decide the final trade and priority.

Use the classification, the unit history, and the priority rules below.
- If the history shows this exact symptom was caused by a different trade before, prefer that trade and explain why.
- Set priority using PRIORITY RULES. Never set emergency unless active damage or a life-safety issue is present.
- Give a one-line reason a coordinator can read at a glance.

CLASSIFICATION:
{classification_json}

UNIT HISTORY:
{unit_history_formatted}

PRIORITY RULES:
{approved_priority_rules}

Respond ONLY with valid JSON:
{ "final_trade": "", "priority": "", "reason": "", "history_note": "" }
OUTPUT
{
  "final_trade": "hvac",
  "priority": "high",
  "reason": "Water near bathroom matches AC condensate line flagged 6 months ago, not a plumbing leak. Active spread = high.",
  "history_note": "Recurring: condensate line cleared on 2025-11-12, same symptom."
}
APINode 6
HTTP Request - Route to Queue
Map final_trade to the correct queue or assigned tech via your routing map, then POST a work order to the PMS/CMMS with trade, priority, reason, and history note attached.
Output: Work order created. Status set to "Routed - pending coordinator review".
ACTIONNode 7
Notify & Flag
Send the coordinator a summary line. Emergency or low-confidence calls get an immediate alert; everything else lands in the morning queue.
Output: Coordinator notified. Ticket ready for one-tap approve or override.
MVP vs Advanced — Where To Start
MVP — START HERE
  • Single intake channel (portal webhook)
  • LLM trade classification only
  • Maintenance-history Google Sheet
  • Fixed priority rules
  • Routed ticket posted to a shared queue
  • Coordinator alert by email
ADVANCED — ADD LATER

    Full Video Walkthrough Coming Soon

    From raw request to routed ticket - step by step.

    Register to be notified

    Everything on this page is free to learn.

    When you're ready to build — do it yourself or bring us in.

    OTHER AGENTS IN LEASING & MARKETING

    Converts QA failures into structured follow-up tasks
    Applies consistent category and severity rules across all tickets
    Tracks parts-dependent jobs so tickets don't silently stall
    Fills the gaps in a request before a tech is dispatched

    Frequently asked questions

    Maintenance Triage and Dispatch is an AI agent that classifies trade, sets priority from history, and triggers correct dispatch.
    The wrong tech showed up. Twice. The Maintenance Triage and Dispatch addresses this — it classifies trade, sets priority from history, and triggers correct dispatch.
    No — your team stays in control. Your coordinator approves every dispatch and overrides any call the agent gets wrong. The agent handles the reading, the trade classification, the history lookup, and the priority rules. It removes the guesswork on routing, not the decision to send.