A real estate CRM with automated lead capture from Meta (Facebook + Instagram) advertising campaigns, integrated calling with AI-assisted call summarization, and a property catalogue at 100,000+ records scale.
Real estate agents in our client's market lived inside two silos: their Meta ad campaigns generating leads, and their CRM holding properties. Leads arrived as inbox notifications, got copy-pasted into spreadsheets, then assigned to agents over WhatsApp. The drop-off between "lead generated" and "lead contacted" was where most revenue leaked.
We built a CRM that closes that loop. Leads from Meta Lead Ads flow directly into the CRM via webhook, get auto-assigned to the right agent based on property type and territory, and surface to the agent on their phone — with the calling functionality built into the platform.
Head of Engineering & Delivery (CTO) — Vriksha Techno Solutions
- Designed the lead-capture-to-assignment pipeline architecture
- Owned the Meta Lead Ads API integration, including webhook reliability and idempotent processing
- Architected the property data model for 100,000+ records with sub-second query performance for 50+ concurrent agents
- Specified the AI call summarization integration and managed delivery
- Made the architectural call between native telephony integration vs. third-party (e.g., Twilio)
flowchart TD
A[Meta Ads Manager] -->|Lead Submitted| B[Meta Lead Ads Webhook]
B --> C[Lead Ingestion Service]
C --> D[Idempotency + Dedup]
D --> E[Lead Router]
E --> F[Agent Assignment Engine]
F --> G[Notification Service]
G --> H[Agent Mobile App]
H --> I[Integrated Call Module]
I --> J[Telephony Provider]
J --> K[Call Recording]
K --> L[Transcription Service]
L --> M[AI Summarizer - OpenAI]
M --> N[CRM Lead Record]
O[Property Catalogue 100K+] --> N
N --> P[Operator Dashboard]
H --> N
style M fill:#1f3864,color:#fff
style F fill:#1f3864,color:#fff
- Backend: NestJS, TypeScript, Node.js
- Database: MySQL (property catalogue with optimized indexes), Redis (assignment queue + caching)
- AI: OpenAI API for call summarization and lead-quality scoring
- Integrations: Meta Lead Ads API, telephony provider for in-platform calls
- Frontend: Flutter (agent mobile app — primary surface), React (operator/admin dashboard)
- Infrastructure: AWS (EC2 application tier, S3 for call recordings, CloudWatch monitoring)
Webhook idempotency from day one. Meta retries webhooks aggressively on transient failures. Without idempotent processing, a single lead can be assigned twice — to two different agents — which is operationally worse than missing a lead entirely. We made the lead ingestion layer idempotent by Meta lead ID before any business logic ran.
Auto-assignment as a pluggable engine, not a hard-coded rule. Different clients had different assignment rules: round-robin, territory-based, property-type specialist, or hybrid. We built the assignment engine as a strategy pattern with config per tenant rather than baking rules in. Saved us from rewrites every time a client wanted custom behaviour.
Catalogue indexed for read patterns, not write patterns. With 100,000+ active property records and 50+ daily concurrent agents searching/filtering, our access pattern was overwhelmingly reads. We denormalized aggressively, added composite indexes for the most common filter combinations (location + price + type + status), and used Redis to cache hot search results.
AI summarization as a non-blocking step. Calls happen in real time. Agents can't wait for an AI summary before logging the call outcome. We made the summarization an async job that fills in afterward — the agent logs basic outcome immediately, the AI fills in the conversation summary within minutes. Users perceived this as "the system magically wrote the notes" while engineering treated it as a queue worker.
Tight loop between AI confidence and human review. The summary AI returns a confidence indicator. Low-confidence summaries are flagged for the agent to review and edit. High-confidence summaries are accepted as-is. This kept the AI useful without it ever being authoritative on customer records.
- 100,000+ active property records in the catalogue
- 50+ daily concurrent agents using the platform
- Lead-to-first-contact time materially reduced through auto-assignment + mobile push
- AI call summarization eliminated most manual note-taking, recovering agent time for selling
(Specific conversion rates, revenue impact, and tenant data are confidential.)
- Move from MySQL to Postgres earlier. Some of our search workloads (especially geo + range filters across price/area) would have been simpler in Postgres with PostGIS. We made it work with MySQL but the geo logic was harder than it needed to be.
- Treat call recordings as a separate domain from the start. We initially co-located recordings with call metadata in S3. Later we had to split them when retention/compliance requirements diverged. A clean separation from day one would have saved migration work.
- Build the AI confidence-gating UI before deploying the AI. We deployed AI summarization first, then realized agents needed a clear "human-edit-required" indicator. Should have shipped the trust layer with the AI, not after.
This is a sanitized case study of production work delivered to a private client. Source code is not included due to confidentiality. Architectural decisions, technology choices, and lessons described here are original and reflect my direct engineering leadership on the project.