Property management call routing

Build a call routing workflow for property management that dynamically routes calls based on tenant status, inquiry type, and agent availability.
Property Management Workflow

Overview

Build a property management call routing workflow that determines transfer destinations dynamically using tenant verification, inquiry type analysis, and real-time agent availability. This approach uses visual workflow nodes with API Request nodes for maximum routing flexibility.

Workflow Capabilities:

  • Tenant status verification and prioritization
  • Inquiry type classification for specialist routing
  • Real-time agent availability and queue management
  • Emergency routing for urgent maintenance issues

What You’ll Build:

  • Visual workflow with conditional routing logic
  • API Request nodes for dynamic destination logic
  • Tenant verification with CRM integration
  • Emergency escalation with priority queuing

Quick Start: Create the Complete Workflow

Use this cURL command to create the entire property management workflow in one shot:

Complete Workflow Creation
$curl -X POST https://api.vapi.ai/workflow \
> -H "Authorization: Bearer $VAPI_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "name": "Property Management Call Router",
> "nodes": [
> {
> "type": "conversation",
> "name": "Initial Greeting",
> "isStart": true,
> "prompt": "You are a helpful property management assistant for Riverside Property Management. Start by greeting the caller and asking how you can help them today. Listen to determine: Is this an emergency/urgent maintenance issue? What type of inquiry is this (maintenance, lease, rent, general)? Keep responses under 25 words and be professional.",
> "model": {
> "provider": "openai",
> "model": "gpt-4"
> },
> "variableExtractionPlan": {
> "schema": {
> "type": "object",
> "properties": {
> "inquiry_type": {
> "type": "string",
> "description": "Type of inquiry",
> "enum": ["emergency", "maintenance", "lease", "rent", "general"]
> },
> "caller_phone": {
> "type": "string",
> "description": "Caller phone number for tenant lookup"
> }
> }
> }
> }
> },
> {
> "type": "conversation",
> "name": "Emergency Handling",
> "prompt": "This is an emergency maintenance situation. Tell the caller you understand this is an emergency and that you are immediately connecting them with emergency maintenance. Keep the interaction brief and gather only essential details about the emergency.",
> "model": {
> "provider": "openai",
> "model": "gpt-4"
> },
> "variableExtractionPlan": {
> "schema": {
> "type": "object",
> "properties": {
> "emergency_details": {
> "type": "string",
> "description": "Brief description of emergency"
> }
> }
> }
> }
> },
> {
> "type": "tool",
> "name": "Transfer to General Office",
> "tool": {
> "type": "transferCall",
> "destinations": [
> {
> "type": "number",
> "number": "+12025551234",
> "message": "Connecting you to our office team who will assist you with your inquiry."
> }
> ]
> }
> }
> ],
> "edges": [
> {
> "from": "Initial Greeting",
> "to": "Emergency Handling",
> "condition": {
> "type": "ai",
> "prompt": "Route to emergency handling if the caller has an emergency or urgent maintenance issue"
> }
> },
> {
> "from": "Initial Greeting",
> "to": "Transfer to General Office",
> "condition": {
> "type": "ai",
> "prompt": "Route to transfer for all non-emergency inquiries (maintenance, lease, rent, general)"
> }
> },
> {
> "from": "Emergency Handling",
> "to": "Transfer to General Office",
> "condition": {
> "type": "ai",
> "prompt": "After gathering emergency details, transfer to office"
> }
> }
> ]
> }'

Replace $VAPI_API_KEY with your actual API key from the Vapi Dashboard. Update the phone number in the transferCall destination to your actual office number.

Once created, you can retrieve the workflow ID and attach it to a phone number for testing.

Test Workflow Creation

After creating the workflow, you can test it and get the workflow ID:

$# First, create the workflow using the command above, then:
>curl -X GET https://api.vapi.ai/workflow \
> -H "Authorization: Bearer $VAPI_API_KEY" \
> | jq '.[] | select(.name == "Property Management Call Router") | {id: .id, name: .name, nodes: (.nodes | length), edges: (.edges | length)}'

You’ll need jq installed for JSON parsing. On macOS: brew install jq, on Ubuntu: sudo apt-get install jq

API Response Structure

When you create the workflow, you’ll receive a response like this:

1{
2 "id": "wf_1234567890abcdef",
3 "name": "Property Management Call Router",
4 "orgId": "org_1234567890abcdef",
5 "createdAt": "2024-01-15T10:30:00.000Z",
6 "updatedAt": "2024-01-15T10:30:00.000Z",
7 "nodes": [
8 {
9 "id": "greeting",
10 "type": "conversation",
11 "name": "Initial Greeting",
12 "isStart": true,
13 "firstMessage": "Hello! You've reached Riverside Property Management...",
14 "systemPrompt": "You are a helpful property management assistant...",
15 "model": {
16 "provider": "openai",
17 "model": "gpt-4"
18 },
19 "extractVariables": [...]
20 },
21 // ... more nodes
22 ],
23 "edges": [
24 {
25 "id": "greeting_to_lookup",
26 "source": "greeting",
27 "target": "tenant_lookup",
28 "condition": "Always route to tenant lookup after greeting"
29 },
30 // ... more edges
31 ]
32}

Key Fields for Integration

FieldDescriptionUsage
idWorkflow IDUse this to attach workflow to phone numbers
nameWorkflow nameFor identification in dashboard
nodesArray of workflow nodesConversation and tool nodes
edgesArray of connectionsDefine the flow between nodes
createdAtCreation timestampFor tracking and reference

Node Types in This Workflow

  • Conversation Nodes: Handle AI conversations with tenants
  • Tool Nodes: Execute API calls for tenant lookup and routing
  • Transfer Nodes: Route calls to appropriate agents

Prerequisites

  • A Vapi account
  • Property management system API or tenant database
  • (Optional) Agent availability tracking system

Scenario

We will build a call routing workflow for Riverside Property Management that intelligently routes tenant calls based on their status, inquiry type, and agent availability.


1. Create a Workflow

2

Create new workflow

  • Click Create Workflow
  • Name: Property Management Call Router
  • Select blank template to start with basic call start node
  • Click Create Workflow
3

Configure the initial greeting

Click on the conversation node and configure:

Prompt:

You are a helpful property management assistant for Riverside Property Management. Start by greeting the caller and asking how you can help them today. Listen to determine: Is this an emergency/urgent maintenance issue? What type of inquiry is this (maintenance, lease, rent, general)? Keep responses under 25 words and be professional.

Variable Extraction Schema:

1{
2 "type": "object",
3 "properties": {
4 "inquiry_type": {
5 "type": "string",
6 "description": "Type of inquiry",
7 "enum": ["emergency", "maintenance", "lease", "rent", "general"]
8 },
9 "caller_phone": {
10 "type": "string",
11 "description": "Caller phone number for tenant lookup"
12 }
13 }
14}

2. Add Tenant Verification Node

1

Add API Request node for tenant lookup

Add an API Request node after the greeting:

Node Configuration:

  • Node ID: tenant_lookup
  • HTTP Method: POST
  • URL: https://your-property-system.com/api/tenants/lookup
  • Headers: Authorization: Bearer YOUR_API_KEY
  • Body:
1{
2 "phone": "{{caller_phone}}",
3 "inquiry_type": "{{inquiry_type}}"
4}
2

Configure response mapping

Map the API response to workflow variables:

  • tenant_status → Extract from response.tenant.status
  • property_address → Extract from response.tenant.property
  • account_standing → Extract from response.tenant.account_standing
  • emergency_contact → Extract from response.tenant.emergency_contact
3

Add error handling

Configure what happens if the API call fails:

  • On Error: Route to general agent queue
  • Error Message: “I’ll connect you with our general team who can help.”

3. Build Emergency Routing Logic

1

Add emergency detection node

Add a Conversation node for emergency handling:

Condition: inquiry_type == "emergency"

First Message:

I understand this is an emergency. Let me immediately connect you with our emergency maintenance team. Please stay on the line.

System Prompt:

This is an emergency maintenance situation. Confirm the emergency details quickly and route to emergency maintenance immediately. Keep interaction brief.
2

Add emergency API routing

Add an API Request node to get emergency destination:

URL: https://your-system.com/api/routing/emergency Method: POST Body:

1{
2 "tenant_id": "{{tenant_id}}",
3 "property": "{{property_address}}",
4 "inquiry_type": "emergency",
5 "priority": "high"
6}
3

Add emergency transfer node

Add a Transfer Call node:

  • Destination: Use the phone number from the API response
  • Transfer Plan: Include emergency context and tenant information
  • Priority: Set to highest priority for immediate routing

4. Create Inquiry-Based Routing

1

Add maintenance routing branch

Add API Request node for maintenance team routing:

Condition: inquiry_type == "maintenance" URL: https://your-system.com/api/routing/maintenance Body:

1{
2 "tenant_id": "{{tenant_id}}",
3 "property": "{{property_address}}",
4 "inquiry_type": "maintenance",
5 "tenant_status": "{{tenant_status}}"
6}

Response should include:

  • Available maintenance coordinator phone
  • Estimated wait time
  • Work order creation capability
2

Add leasing office routing

Add API Request node for leasing inquiries:

Condition: inquiry_type == "lease" URL: https://your-system.com/api/routing/leasing Body:

1{
2 "tenant_id": "{{tenant_id}}",
3 "property": "{{property_address}}",
4 "inquiry_type": "lease",
5 "account_standing": "{{account_standing}}"
6}
3

Add rent/billing routing

Add API Request node for billing department:

Condition: inquiry_type == "rent" URL: https://your-system.com/api/routing/billing Body:

1{
2 "tenant_id": "{{tenant_id}}",
3 "account_standing": "{{account_standing}}",
4 "inquiry_type": "rent"
5}

5. Add Agent Availability Logic

1

Create availability checking flow

Before each transfer, add an API Request to check agent availability:

URL: https://your-system.com/api/agents/availability Method: GET Query Parameters: department={{department}}&priority={{priority}}

Response includes:

  • Available agents with phone numbers
  • Current queue length
  • Estimated wait times
2

Add queue management logic

Add conditional routing based on availability:

If agents available: Direct transfer to agent If queue exists: Inform caller of wait time and offer callback If all busy: Route to voicemail or priority callback system

3

Configure callback handling

Add API Request node for callback scheduling:

URL: https://your-system.com/api/callbacks/schedule Body:

1{
2 "tenant_id": "{{tenant_id}}",
3 "phone": "{{caller_phone}}",
4 "inquiry_type": "{{inquiry_type}}",
5 "priority": "{{priority}}",
6 "requested_time": "{{preferred_callback_time}}"
7}

6. Build Transfer Nodes with Context

1

Create dynamic transfer destinations

Use the API response data to populate transfer nodes:

Maintenance Transfer:

  • Destination: {{maintenance_agent_phone}}
  • Message: “Connecting you to {{agent_name}} from our maintenance team.”
  • Transfer Plan: Include tenant property address and issue details

Leasing Transfer:

  • Destination: {{leasing_agent_phone}}
  • Message: “Transferring you to our leasing office.”
  • Transfer Plan: Include tenant status and lease information

Billing Transfer:

  • Destination: {{billing_agent_phone}}
  • Message: “Connecting you with our billing department.”
  • Transfer Plan: Include account standing and payment history
2

Configure transfer context

Each transfer node should include rich context:

Transfer Plan Summary
Tenant: {{tenant_name}} at {{property_address}}
Account Status: {{account_standing}}
Inquiry Type: {{inquiry_type}}
Previous Context: {{conversation_summary}}
Priority: {{priority_level}}

7. Add Error Handling and Fallbacks

1

Create fallback routing

Add API Request node for fallback scenarios:

Triggers:

  • API lookup failures
  • No available agents
  • Unknown inquiry types
  • System errors

URL: https://your-system.com/api/routing/fallback Body:

1{
2 "phone": "{{caller_phone}}",
3 "error_type": "{{error_reason}}",
4 "original_inquiry": "{{inquiry_type}}"
5}
2

Add general queue routing

Create Transfer Call node for general queue:

Destination: Main office line Message: “Let me connect you with our general team who can assist you.” Transfer Plan: “Call requires general assistance - routing details unavailable”

3

Configure voicemail option

Add End Call node with voicemail message:

Condition: All agents busy and caller declines callback Message: “Please leave a detailed voicemail including your name, property address, and the nature of your request. We’ll call you back within 4 hours.”


8. Test Your Property Routing Workflow

1

Create a phone number

  • Navigate to Phone Numbers in your dashboard
  • Click Create Phone Number
  • Assign your property management workflow
  • Configure any additional settings
2

Test different routing scenarios

Call your number and test various scenarios:

  • Emergency maintenance calls
  • Regular maintenance requests from verified tenants
  • Leasing inquiries from prospective tenants
  • Billing questions from current tenants
  • Calls from unrecognized phone numbers
3

Monitor workflow performance

Check your workflow analytics to verify:

  • Call routing patterns
  • Emergency response times
  • Variable extraction accuracy
  • Transfer success rates

API Integration Examples

Your property management system can integrate with the workflow using these API endpoints:

Tenant Lookup Endpoint

1POST /api/tenants/lookup
2Content-Type: application/json
3
4{
5 "phone": "+1234567890",
6 "inquiry_type": "maintenance"
7}

Response:

1{
2 "tenant": {
3 "id": "tenant_123",
4 "name": "John Smith",
5 "status": "active",
6 "property": "123 Main St, Apt 4B",
7 "account_standing": "good"
8 },
9 "routing_suggestion": "maintenance_team"
10}

Agent Availability Check

1GET /api/agents/availability?department=maintenance&priority=normal

Response:

1{
2 "available_agents": [
3 {
4 "id": "agent_456",
5 "name": "Mike Johnson",
6 "phone": "+15551234567",
7 "department": "maintenance"
8 }
9 ],
10 "queue_length": 2,
11 "estimated_wait_minutes": 5,
12 "department_status": "available"
13}

Emergency Routing

1POST /api/routing/emergency
2Content-Type: application/json
3
4{
5 "tenant_id": "tenant_123",
6 "property": "123 Main St, Apt 4B",
7 "inquiry_type": "emergency"
8}

Response:

1{
2 "destination": "+15559876543",
3 "agent_name": "Emergency Maintenance",
4 "ticket_id": "EM_789",
5 "priority": "critical"
6}

Advanced Workflow Features

Queue Management with Priorities

Configure priority-based routing in your tenant lookup API:

1{
2 "tenant": {
3 "tier": "commercial",
4 "account_standing": "good",
5 "inquiry_type": "emergency"
6 },
7 "routing_priority": "critical"
8}

Priority levels:

  • Critical: Emergency situations, commercial tenants
  • High: Good standing tenants with urgent issues
  • Normal: Standard maintenance and lease inquiries
  • Low: Delinquent accounts with non-urgent matters

Business Hours Routing

Configure time-based routing logic:

1{
2 "business_hours": {
3 "weekdays": "9:00-17:00",
4 "weekends": "10:00-15:00"
5 },
6 "after_hours_routing": {
7 "emergency": "+15559876543",
8 "general": "voicemail"
9 }
10}

Next Steps

You’ve built a sophisticated property management call routing workflow! Consider these enhancements: