Real-Time Lead Routing CRM with Next.js & Supabase
Most real estate agencies lose leads in the gap between a form submission and a human response. The average response time in the industry is 47 minutes. In that window, a lead has already called three competitors. (The UX patterns that cause this at the website level are covered in Why Your Real Estate Website Is Losing Leads.)
This post breaks down the system I built to close that gap entirely.
The Problem
The client — a Dubai real estate brokerage — was running on a mix of WhatsApp forwards, a shared Google Sheet, and gut instinct. Three agents were spending 2+ hours a day on manual data entry alone.
When a lead came in from the website, it went into an inbox nobody reliably checked. Leads from Meta Ads landed in a separate tool. The agents compared notes in a WhatsApp group.
The result: a 60% lead response rate at best, and zero visibility across the pipeline.
The Architecture
Website Form / Meta Lead Ads
│
▼
Supabase Edge Function
(intake + deduplication)
│
├──► Supabase DB (leads table)
│
├──► Routing Logic (round-robin / priority)
│
└──► Webhook → WhatsApp Business API
→ Email notification
Intake Layer
All lead sources — website forms, Meta Lead Ads, walk-ins — push to a single Supabase Edge Function. This function:
- Deduplicates by phone number (prevents the same lead going to two agents)
- Enriches the record with UTM parameters to track which campaign drove it
- Stamps a
received_attimestamp for SLA tracking
Routing Logic
Routing is a simple priority queue stored in Supabase. Agents have a capacity field (max active leads) and a last_assigned_at timestamp. The function picks the next available agent with the lowest last_assigned_at.
This replaced a WhatsApp group argument happening three times a week.
Notification Layer
Once assigned, the agent gets:
- A WhatsApp message via the WhatsApp Business API (immediate, mobile-native)
- An email with full lead context
Both fire within under 2 seconds of the form submission.
The CRM Dashboard
The frontend is a Next.js App Router application with a Supabase real-time subscription. Agents see their pipeline update live — no page refresh, no "did that lead come in yet?" questions.
Key views:
- My Pipeline — leads assigned to the logged-in agent, grouped by stage
- All Leads — manager-only view with filters by source, stage, and agent
- SLA Monitor — flags leads that haven't been contacted within 15 minutes
Results
After 60 days in production:
| Metric | Before | After |
|---|---|---|
| Response time | 47 min avg | < 2 min |
| Data entry time | 2 hrs/day | ~10 min |
| Lead conversion rate | baseline | +45% |
| Agent satisfaction | complaints weekly | no complaints |
What I'd Do Differently
One thing I underestimated: agent adoption. The WhatsApp notification was the key — agents were already living in WhatsApp, so the CRM felt like it came to them rather than asking them to go somewhere new.
If I built this again I'd add WhatsApp reply-to-update directly in the pipeline (read: an agent replies "interested" and the lead stage updates automatically). That's the next iteration.
If you're running paid ads to this pipeline, the landing page setup that makes those leads actually convert is in The Landing Page That Fixed Our Google Ads ROI.
Building something similar for your team? Get in touch — this kind of system typically takes 3–4 weeks to ship.