AI

Build Log: Call Intelligence Dashboard for 20+ Dental Clinics

How I built the Call Intelligence Platform — a real-time call-scoring dashboard — from the first webhook to a live multi-tenant system processing every inbound call across 20+ locations.
4 minutes to read2 months agoIgnasius Sevandri
June 24, 2026

The brief was simple: every inbound call to every clinic, scored automatically, visible in a single dashboard. No manual review, no sampling. 100% coverage.

Here's how I built it.

The Starting Point

The client ran 20+ dental practices through GoHighLevel. Every location had its own sub-account, its own call log, its own staff. The existing process: a manager would occasionally listen to random calls and score them manually. Coverage was maybe 5% on a good week. The rest was invisible.

The ask: make every call visible, scored, and reportable — without adding headcount.

Architecture Overview

The system has four layers:

  1. Ingestion — GoHighLevel webhooks fire on every call completion
  2. Transcription — Audio is passed to a transcription service and converted to text
  3. Scoring — Google Gemini evaluates the transcript against an 8-step framework
  4. Reporting — Results land in a central database and push to three delivery channels

Each layer is a separate n8n workflow. They communicate via an internal queue so a transcription delay doesn't block the scoring step from starting.

The Webhook Setup

GoHighLevel supports outbound webhooks at the sub-account level. With 20+ sub-accounts, I wrote a setup script that configured identical webhooks across all of them pointing to a single n8n endpoint.

The webhook payload includes: call direction (inbound/outbound), duration, caller ID, the sub-account ID, and — critically — a link to the call recording.

The first n8n workflow receives the webhook, validates the payload, filters out calls under 30 seconds (voicemails and hang-ups), and queues the rest for processing.

Transcription

Call recordings come as GHL-hosted audio files. The workflow downloads each file, sends it to a transcription API, and stores the result with the call metadata in a Postgres database. Typical turnaround: under 60 seconds per call.

One edge case: calls where the patient speaks in a mix of English and Tagalog (common in some of the clinic's markets). The transcription model handles code-switching reasonably well, but Gemini needed explicit instruction to handle mixed-language transcripts gracefully rather than flagging them as low-confidence.

The Scoring Framework

The scoring workflow takes each transcript and passes it to Gemini with a structured prompt built around an 8-step call quality framework:

  1. Greeting and identification
  2. Active listening — does the staff acknowledge the patient's concern before offering information?
  3. Appointment pitch — is a booking offered within the first two minutes?
  4. Objection handling — price, timing, fear
  5. Confirmation — is the appointment confirmed with full details?
  6. Follow-up intent — is a follow-up mentioned if no booking happens?
  7. Closing — professional close with next steps
  8. Overall sentiment

The output is a JSON object with a score per step (0–2), a flag for any critical failure, and a one-sentence summary of what went well and what to improve.

Getting Gemini to return consistent JSON took iteration. The final prompt uses a chain-of-thought prefix that asks the model to reason through each step before outputting, which dramatically reduced hallucinated scores on edge cases.

The Dashboard

Scored calls land in a Postgres database with 16+ tables covering calls, scores, agents, locations, and aggregated metrics. The frontend is a custom dashboard that shows:

  • Call volume by location, by day
  • Average score per location and per staff member
  • Missed vs. answered ratio
  • Flagged calls (critical failures) highlighted for review
  • Trend lines for booking rate over time

One addition that the client specifically asked for: a comparison panel showing AI-handled calls (the clinic also uses a voice agent) vs. human-handled calls, with side-by-side scoring. This surfaced something interesting — the AI agent scored higher on steps 1, 3, and 5 consistently, while human agents scored higher on steps 2 and 4 (active listening and objection handling).

Reporting Delivery

The daily report runs at 7:00 AM via a scheduled n8n workflow. It queries the prior day's data, formats a structured summary per location, and delivers via:

  • SMS — a short scorecard text to each location manager
  • Email — a formatted HTML email with location breakdown and flagged calls
  • Dashboard — the persistent web dashboard for deeper drill-down

The weekly report aggregates seven days of data and adds trend analysis — whether scores are improving or declining week-over-week at each location.

What I'd Do Differently

The transcription step is the slowest part of the pipeline. Average 45–90 seconds, which is fine for a daily reporting context but would be too slow for a real-time alert system. If the client wanted same-minute alerts on critical call failures, I'd move to a streaming transcription approach instead of batch.

The dashboard is custom-built, which gave full control over the data model and display. In retrospect, for a simpler reporting need, a Retool or Metabase setup on top of the same Postgres schema would have been faster to deploy — though it would have been less flexible for the location-vs-AI comparison panel.

Current State

The system has been running for several months across all 20+ locations. Every inbound call is scored. The client's operations team now has a weekly review meeting that runs entirely off the dashboard data — no manual listening, no sampling. Coverage went from under 5% to 100%.

Newsletter

Automation Playbooks, Delivered

New playbooks and build logs on AI automation — no fluff, no cadence pressure. When something is worth sharing, it lands in your inbox.