A lead source intelligence system for a Klang Valley rental agency running 10 listings across 5 enquiry channels. Multi-source attribution, lead quality tracking, and a two-audience white-label reporting layer, modeled on a real Upwork market demand signal.
At its heart, the system answers one question for a rental agency: where do our leads actually come from, and which sources are worth the money?
A property agent receives enquiries through many doors: portal chats, WhatsApp messages, phone calls, ad lead forms. Each platform only sees its own door. This system collects every enquiry into one place, tags it with its source, its cost, and its outcome, and presents the combined picture in two formats: a detailed internal dashboard for the agent, and a simple white-label report for each property owner.
The agency principal / agent. Decides monthly where marketing ringgit goes, which listings need price reviews, and whether enquiries are being lost. Needs operational detail.
The property owner (landlord). Receives a monthly branded one-page report proving the agent is actively marketing their unit. Needs plain language and confidence, not metrics.
Sourced from a live Upwork posting: a UK marketing agency seeking a white-label, multi-source reporting system with call tracking, lead quality analysis, two-audience dashboards, and monthly written insights, cloneable across clients. This build transplants every demanded mechanism into the Malaysian rental property vertical: attribution across paid and free channels, the untracked-phone-lead problem, the volume-versus-quality trap, and the clone-per-client architecture (here, clone-per-listing and clone-per-owner).
| ID | Listing | Area | Segment | Rent (RM/mo) | Role in dataset |
|---|---|---|---|---|---|
| L01 | Arte Mont Kiara | Mont Kiara | Whole unit | 1,749 | Signed Feb · PropertyGuru |
| L02 | Nexus Residence (room) | Cheras | Room | 899 | Signed Apr · Meta Ads |
| L03 | J.Dupion (female room) | Cheras | Room | 799 | Active · mismatch pattern host |
| L04 | 28 Boulevard studio | Ampang | Studio | 1,599 | Active |
| L05 | Nexus Residence (whole unit) | Cheras | Whole unit | 2,999 | Signed May · comparison anchor for L09 |
| L06 | J.Dupion (master room) | Cheras | Room | 1,200 | Signed Mar · Referral |
| L07 | Lavile Kuala Lumpur | Maluri | Whole unit | 1,800 | Star performer · signed in 3 weeks |
| L08 | M Vertica (room) | Maluri | Room | 850 | Signed Apr · Referral |
| L09 | Sunway Velocity Two | Maluri | Whole unit | 3,400 | Planted stale listing |
| L10 | Razak City studio | Sungai Besi | Studio | 1,350 | Signed Mar · Google Ads |
All identities fictionalized: agent persona "Adeline Khoo (PEA 9183), Klang Valley Homes Realty". Listing structures modeled on real KL market patterns.
| Source | Category | Cost structure | Analytical role |
|---|---|---|---|
| PropertyGuru | Platform | Subscription + boosts | Premium portal workhorse |
| Mudah.my | Platform | Near-free + bumps | High volume, low quality trap |
| Google Ads | Search ad | Campaign spend | Cleanest cost-per-lead channel, intent leads |
| Meta Ads | Social media | Campaign spend | Visual targeting, room segment specialist |
| WhatsApp referral | Referral | RM0 | Quality benchmark, the invisible champion |
Source (where they came from) and contact method (portal chat, WhatsApp, phone call, lead form) are tracked as separate columns. That separation is the attribution layer.
An enquiry is qualified when the prospect's requirement matches the listing (gender rule, occupancy, fit), the intended move-in is within 30 days, and they remain responsive past the first exchange. Everything else is raw volume.
no_replylowballrequirement_mismatchbudget_mismatchno_showlost_to_otherunansweredstill_opentenancy_signed
"Unanswered" is the missed-lead category: a lead the agency paid for and never replied to. It inherits the call-tracking DNA of the source job.
| KPI | Formula | Audience |
|---|---|---|
| Enquiries / Qualified enquiries | Counts; qualified per written rule | Both / Internal |
| Cost per enquiry (CPE) | Source cost ÷ enquiries | Internal |
| Cost per qualified enquiry | Source cost ÷ qualified enquiries | Internal |
| Cost per viewing booked | Source cost ÷ viewings booked | Both |
| Cost per tenancy (conversion) | Source cost ÷ tenancies signed | Both · headline |
| Enquiry-to-viewing rate | Viewings booked ÷ enquiries | Both |
| Viewing show-up rate | Attended ÷ booked | Internal |
| Source quality score | Qualified ÷ total, per source | Internal |
| Median response time | median(first response − enquiry time) | Internal |
| Unanswered rate | Unanswered ÷ enquiries (split by after-hours) | Internal |
| Days on market | Signed date (or today) − listed date | Both |
| Enquiry velocity / stale flag | Enquiries per week, 4-week trend; flag if down ≥50% vs first 2 weeks and still open | Internal |
The owner report uses only the "Both" rows, translated to plain language: 12 people enquired, 5 viewed, here is what we are doing next.
| Source | RM / month | 6-month total | Allocation rule |
|---|---|---|---|
| PropertyGuru | 450 | 2,700 | Portfolio-level: spread by days listed |
| Mudah.my | 60 | 360 | Portfolio-level: spread by days listed |
| Google Ads | 600 | 3,600 | Campaign-level: 3 campaigns by segment |
| Meta Ads | 400 | 2,400 | Campaign-level: 2 campaigns by segment |
| WhatsApp referral | 0 | 0 | Goodwill cost excluded, stated in README |
| Total | 1,510 | 9,060 | All assumptions stated openly |
Eight patterns were written into the data generator deliberately, then verified after generation. They become the case study's findings.
The Mudah inversion (headline). 40% of all enquiry volume, 15% qualified rate, 5% viewing rate, zero tenancies in six months. The chart everyone remembers.
Google Ads: pay more, get tenants. Highest cost per enquiry (RM31) but ~50% qualified and the best paid-channel viewing rate. Two tenancies at RM1,800 each.
Referral: the invisible champion. 9% of volume, 67% qualified, two tenancies at RM0. Justifies formalizing a referral ask at every signing.
The stale listing. Sunway Velocity Two (RM3,400) collapses ~70% in enquiry velocity after week 2 while comparable Nexus at RM2,999 keeps moving. Recommendation: reprice toward RM3,000 to 3,100.
The after-hours leak. Unanswered rate runs 20% after-hours versus 7% in office hours, roughly 3x. Quantified as ~RM700 of paid leads lost.
Channel x segment. Meta converts for rooms only; Google for whole units and studios. Stop running every listing on every channel.
The star performer. Lavile (RM1,800, Maluri) signs within 3 weeks via Google Ads, giving the dashboard a healthy benchmark and the owner report a success story.
Portfolio sell-through. Monthly volume falls from 299 (Feb) to 64 (May) as 7 of 10 listings sign. The insight layer flags a restock warning: success creates its own pipeline problem.
| Source | Tenancies | Cost per tenancy | Verdict |
|---|---|---|---|
| WhatsApp referral | 2 | RM 0 | Champion |
| PropertyGuru | 2 | RM 1,350 | Workhorse |
| Google Ads | 2 | RM 1,800 | Quality engine |
| Meta Ads | 1 | RM 2,400 | Rooms only |
| Mudah.my | 0 | Undefined | Volume trap |
| File | Grain | Key columns |
|---|---|---|
| listings.csv | 1 row per listing (10) | listing_id, property_name, area, segment, asking_rent_myr, gender_rule, listed_date, status, signed_date, signed_source |
| enquiries.csv | 1 row per enquiry (~1,140) | enquiry_id, listing_id, datetime, source, contact_method, campaign, move_in_days, qualified, responded, first_response_min, after_hours, viewing_booked, viewing_attended, outcome |
| ad_spend.csv | month x campaign (30) | month, source, campaign, spend_myr, target_segment |
| platform_costs.csv | month x platform (12) | month, source, cost_myr |
Window: 1 Dec 2025 to 31 May 2026. Generator: Python (pandas, numpy), fixed seed 2026, all assumptions and planted patterns documented in README.md. Realism rules include weekly seasonality, Jan to Feb intake bump, new-listing lifecycle curves, and after-hours enquiry timing.
A monthly written-recommendations section driven by metric thresholds, with AI-drafted summaries the agent edits. This reuses the KPI Composite Builder's AI-summary engine.
Planning pack. Funnel taxonomy, KPI dictionary, cost model, planted insights, this outline.
Dataset. Generator built, run, and validated against all eight planted patterns.
Data model + internal dashboard. Power BI star schema (enquiries fact, listings dim, cost tables), DAX measures from the KPI dictionary, five pages.
Owner report. Refined Trust HTML one-pager per listing, demonstrated on two listings with two brand skins.
Insights layer. Threshold rules plus AI-drafted monthly notes; sample month of generated recommendations.
Case study. Refined Trust case study page: audience first, decisions and money framing, the cost-per-tenancy table as hero, cloning playbook section.