Logo
Search
API Docs

Property Management: A Squad Walkthrough

Guides

Property Management: A Squad Walkthrough

Overview

This is a full worked example of building a property-management call-routing system as a Squad — three assistants sharing a phone number and handing calls off between each other — using the same underlying mechanics covered in Squad API: Create, Update, List and Squad Routing: Handoff Destinations & Context Engineering. A modern Squad-based approach like this one has superseded the older Workflow-based way of building multi-step call flows, so this walkthrough only covers the Squad approach.

The squad has three members:

  • Router – greets the caller, verifies the tenant using a tenant-lookup tool, and classifies the nature of the inquiry
  • Maintenance Specialist – handles emergency and maintenance requests
  • Leasing Specialist – handles leasing, rent, and general inquiries

Step 1: Create the Tenant-Lookup Tool

Create a function tool the Router can call to verify the caller against your property-management system and pull back their unit and lease details:

curl -X POST "https://api.sulus.ai/tool" \
  -H "Authorization: Bearer $CORE_SYSTEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "function",
    "name": "lookup_tenant",
    "description": "Verify the caller as a tenant and retrieve their unit number and lease status",
    "parameters": {
      "type": "object",
      "properties": {
        "phoneNumber": { "type": "string", "description": "The caller's phone number" }
      },
      "required": ["phoneNumber"]
    },
    "server": {
      "url": "https://your-property-management-system.example.com/lookup-tenant"
    }
  }'

See Custom Function Tools for the full field reference on defining a tool this way, including the difference between permanent and transient tools.


Step 2: Build the Three-Assistant Squad

Define the squad with the Router, Maintenance Specialist, and Leasing Specialist as members. The Router carries the lookup_tenant tool and both handoff destinations:

curl -X POST https://api.sulus.ai/squad \
  -H "Authorization: Bearer $CORE_SYSTEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Property Management Squad",
    "members": [
      {
        "assistant": {
          "name": "Router",
          "model": {
            "provider": "openai",
            "model": "gpt-4o",
            "messages": [{ "role": "system", "content": "Greet the caller, verify them as a tenant using lookup_tenant, then classify their inquiry as emergency, maintenance, leasing, rent, or general and transfer accordingly." }],
            "toolIds": ["LOOKUP_TENANT_ID"]
          },
          "firstMessage": "Thanks for calling. Are you calling about a maintenance issue, a lease question, or something else?",
          "firstMessageMode": "assistant-speaks-first"
        },
        "assistantDestinations": [
          {
            "type": "assistant",
            "assistantName": "Maintenance Specialist",
            "description": "Caller is reporting an emergency, a maintenance issue, or something broken in their unit.",
            "contextEngineeringPlan": { "type": "all" }
          },
          {
            "type": "assistant",
            "assistantName": "Leasing Specialist",
            "description": "Caller has a question about renting a unit, lease terms, rent, renewals, move-in/move-out, or a general inquiry.",
            "contextEngineeringPlan": { "type": "all" }
          }
        ]
      },
      {
        "assistant": {
          "name": "Maintenance Specialist",
          "model": {
            "provider": "openai",
            "model": "gpt-4o",
            "messages": [{ "role": "system", "content": "Maintenance specialist. Collect the unit number, a description of the issue, and its urgency. Prioritize anything reported as an emergency." }]
          }
        }
      },
      {
        "assistant": {
          "name": "Leasing Specialist",
          "model": {
            "provider": "openai",
            "model": "gpt-4o",
            "messages": [{ "role": "system", "content": "Leasing specialist. Answer questions about unit availability, pricing, lease terms, renewals, and rent, and walk callers through application steps." }]
          }
        }
      }
    ]
  }'

See Squad API: Create, Update, List for the full request/response reference for this endpoint.


Inquiry Classification and Routing

Inquiry TypeRoutes To
EmergencyMaintenance Specialist
MaintenanceMaintenance Specialist
LeasingLeasing Specialist
RentLeasing Specialist
GeneralLeasing Specialist

As with any squad, each destination's description is the actual routing logic the model reasons over, not just a label — write it as the specific condition that should trigger that transfer. See Squad Routing: Handoff Destinations & Context Engineering for the complete field reference, including the contextEngineeringPlan options used above to carry the caller's verified tenant details and inquiry forward on every handoff.


Escalating to a Human

On top of the squad, you can add a dynamic transfer tool so either specialist can escalate a call to a human — for example, an emergency that needs an on-call maintenance technician immediately, or a leasing question that needs a property manager. This uses the same dynamic transferCall pattern (an empty destinations array resolved by your own server at the moment of transfer) documented in full on Support Escalation: Dynamic Transfer Routing — see that page for the tool definition, parameter schema, and the transfer-destination-request server event this depends on, rather than repeating that mechanism here.


Testing the Squad

Assign the squad to a phone number, then call in and test each routing path end to end:

  • Call in and report a maintenance issue – confirm the Router verifies you as a tenant via lookup_tenant and hands off cleanly to the Maintenance Specialist
  • Call in with a leasing or rent question – confirm a clean handoff to the Leasing Specialist
  • Call in reporting an emergency – confirm it routes to the Maintenance Specialist and, if you've configured the dynamic transfer tool, that it escalates to a human when appropriate

Listen for whether the tenant's verified details and stated inquiry carry over cleanly after each handoff, since the destinations above use contextEngineeringPlan: { "type": "all" }.