Skip to content
AI Voice Agents
AI Voice Agents12 min read0 views

Build a CallSphere-Style Multi-Agent for an MSP IT Helpdesk

Replace a single voicemail box with 4 specialists (auth, ticketing, password reset, escalation) that talk straight to ConnectWise/Halo PSA — full code.

TL;DR — Single-vendor MSP voice tools (Thread Voice, MSP Process VoiceAssist) are great products but expensive at scale. A 4-specialist setup (auth, ticketing, password reset, escalation) on OpenAI Realtime + your PSA's API does the same job and lives inside your tenant.

What you'll build

A 4-agent IT helpdesk that authenticates the caller against AD or Entra, opens a ticket in ConnectWise PSA or Halo, handles password resets via Microsoft Graph, and escalates to the on-call tech for outages.

Prerequisites

  1. PSA: ConnectWise Manage, Halo PSA, or Autotask.
  2. Identity: Microsoft Graph or Okta.
  3. OpenAI Realtime + Twilio.
  4. Python 3.11+, msal, httpx, openai-agents[voice].
  5. A list of caller-id phone numbers per company for fast match.

Architecture

flowchart TB
  C[Caller] --> TR[Triage]
  TR --> AU[Auth]
  AU --> TK[Ticketing]
  AU --> PW[Password Reset]
  AU --> ES[Escalation]
  TK --> PSA[(PSA API)]
  PW --> GRAPH[(MS Graph)]
  ES --> ONCALL[Twilio voice]

Step 1 — Caller-ID auth

```python @function_tool async def identify_caller(phone: str) -> dict: contact = await psa.contacts.find_by_phone(phone) if not contact: return {"authenticated": False, "next_step": "ask_company_pin"} return {"authenticated": True, "company_id": contact.company_id, "name": contact.name, "tier": contact.support_tier}

@function_tool async def verify_pin(company_pin: str, last_four_phone: str) -> dict: return await psa.auth.verify(pin=company_pin, last4=last_four_phone) ```

Step 2 — Ticketing specialist

```python @function_tool async def open_ticket(company_id: str, contact_id: str, summary: str, severity: str, category: str) -> dict: t = await psa.tickets.create( company_id=company_id, contact_id=contact_id, summary=summary, severity=severity, category=category, source="ai_voice") return {"ticket_id": t.id, "ref": t.ref} ```

Hear it before you finish reading

Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.

Try Live Demo →

Step 3 — Password reset (Microsoft Graph)

```python import msal, httpx

async def graph_token(): app = msal.ConfidentialClientApplication( os.environ["AZ_CLIENT_ID"], authority=f"https://login.microsoftonline.com/{os.environ['AZ_TENANT_ID']}", client_credential=os.environ["AZ_CLIENT_SECRET"]) r = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"]) return r["access_token"]

@function_tool async def reset_password(user_principal_name: str) -> dict: tok = await graph_token() new_pw = secrets.token_urlsafe(12) async with httpx.AsyncClient() as c: r = await c.patch( f"https://graph.microsoft.com/v1.0/users/{user_principal_name}", headers={"Authorization": f"Bearer {tok}"}, json={"passwordProfile": {"forceChangePasswordNextSignIn": True, "password": new_pw}}) if r.status_code in (200, 204): return {"ok": True, "temp_password": new_pw} return {"ok": False, "error": r.text} ```

Step 4 — Outage escalation

```python @function_tool async def escalate_outage(company_id: str, summary: str) -> dict: t = await open_ticket(company_id, None, summary, "P1", "outage") oncall = await rotation.who_is_oncall() twilio.calls.create(to=oncall.phone, from_=BUSINESS_NUMBER, url=f"https://you/escalation?ticket={t['ref']}") return {"ticket_ref": t["ref"], "paged": oncall.name} ```

Step 5 — Triage prompt

```md You are the IT helpdesk front desk for [MSP]. Authenticate via caller-id; if unknown, ask company PIN + last 4 of phone. Then classify: password, outage, ticket. Hand off appropriately. Never share temp passwords on the phone — always SMS. ```

Step 6 — Twilio bridge

Same Realtime bridge pattern; pass From (caller-id) into the agent context as a session metadata field.

Still reading? Stop comparing — try CallSphere live.

CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.

Step 7 — Reporting

```sql SELECT date_trunc('day', occurred_at) AS day, count() FILTER (WHERE outcome = 'ticket_opened') AS tickets, count() FILTER (WHERE outcome = 'pw_reset') AS resets, count(*) FILTER (WHERE outcome = 'escalated') AS escalations FROM call_sessions GROUP BY 1 ORDER BY 1 DESC LIMIT 30; ```

Common pitfalls

  • Voice-readable temp passwords. Don't — SMS only.
  • Caller-ID spoofing. Always require a second factor for password resets.
  • PSA rate limits. ConnectWise caps API calls/min.

How CallSphere does this in production

CallSphere's pattern of "triage → specialist → tool call → escalate" is exactly this design. Healthcare's FastAPI :8084 has 14 HIPAA-grade tools, OneRoof's 10 specialists run over WebRTC + Pion + NATS, Salon's 4 ElevenLabs agents emit GB-YYYYMMDD-### refs. 37 agents · 90+ tools · 115+ DB tables. Pricing $149/$499/$1499 with 14-day trial. /affiliate pays 22% to MSP partners.

FAQ

SOC2? Use SOC2-compliant infrastructure; OpenAI Enterprise has SOC2.

MFA? Always — voice auth is necessary but not sufficient.

Cost per ticket? ~$0.20–$0.50 vs. $4–$8 for a human L1 touch.

Time savings? Reports of 25–40% L1 deflection in MSP studies.

Multi-tenant? company_id in every tool; row-level filtering.

Sources

Share

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.