
A property consultancy came to us running its entire business on three spreadsheets, a shared Drive folder of property photos, and about a dozen WhatsApp groups. That setup had worked at four agents. At twenty-two, it was costing them deals.
The breaking point was attribution. Two agents would unknowingly work the same inbound enquiry and call the same buyer within an hour of each other. The firm found out when the buyer complained. Property details lived wherever the listing agent had put them, so quoting a carpet area or an asking price meant phoning a colleague. Nobody could answer how many active commercial listings do we have under two crore without an afternoon of manual counting.
They asked us for a CRM. What they needed was two products that behave like one — a dashboard for the office and a field app for agents standing in front of clients, reading and writing the same records with no possibility of disagreement.
This is what we built, why the obvious approach would not have worked, and what broke along the way.
Industry | Real Estate / PropTech |
Location | India |
Engagement | Fixed cost |
Duration |
|
Team |
|
Stack | Flutter, Next.js, React, Node.js, PostgreSQL, Razorpay, Firebase, WebSocket |
Headline outcome | 16 modules, 3 platforms live, zero duplicate enquiries |
The client runs a property consultancy in India handling residential resale, commercial leasing and raw land, with a team that spends most of the working day away from a desk. That mix matters more than it sounds. A brokerage doing only residential resale can survive on a simple lead tracker. One handling three asset classes with completely different attributes, different buyers and different sales cycles cannot.
They had grown from four agents to twenty-two without changing how information was stored. Each new agent added another WhatsApp group and another tab in a spreadsheet. Nothing failed dramatically. It degraded — a duplicated call here, a stale price there — until the compounding cost showed up as lost deals.
Two agents, one buyer. Inbound enquiries landed in a shared inbox with no ownership rules. The same buyer regularly got called twice in a morning by colleagues who had no idea the other had made contact. In a market where buyers talk to five brokerages, looking disorganised on the first call is expensive.
Listings nobody trusted. Property specs were split across spreadsheets, chat threads and photo folders that disagreed with each other. Agents quoting carpet area or asking price from memory were wrong often enough that the office had stopped trusting the sheet entirely — which meant everyone went back to phoning each other.
Nothing worked on site. Every useful record was desk-bound. An agent standing at a property who wanted to log a visit or pull a comparable had to call the office and wait, or write it on paper and re-enter it that evening if they remembered.
Reporting meant counting by hand. Basic pipeline questions took hours because there was no single source to query. By the time a report existed, it described a week that had already ended.
The compounding is the real problem. Because listings lived in one place and enquiries in another, no agent could verify anything while standing in front of a client. So they guessed. Every guess created a correction somewhere downstream, and the corrections consumed the time that would have gone into fixing the system.
This is the first question any sensible buyer asks, and it deserves an honest answer rather than a vendor's answer. India has capable CRM products. Zoho, Salesforce, HubSpot and several real-estate-specific Indian platforms all handle lead pipelines competently, and for a lot of brokerages one of them is the right answer. Any development company that tells you otherwise without examining your workflows is selling.
Here is where buying loses for a business like this one.
Four property categories that share almost no attributes. A shop, a two-bedroom flat and an agricultural plot have different field sets, different validation rules and different area semantics. Generic CRMs model a deal as an opportunity with custom fields attached. That works until you have four categories with genuinely different shapes, at which point you are maintaining one enormous form where most fields are blank and irrelevant, and agents start skipping fields because the form is exhausting. Field quality collapses, and a CRM with bad data is worse than a spreadsheet because people trust it more than they should.
Ownership enforced by the server, not by convention. The duplicate-contact problem is not solved by a field labelled "assigned agent." It is solved when the API refuses to let a second agent act on a lead someone else owns. Most products treat assignment as metadata that governs a view. That is a different guarantee, and it is not the one this client needed.
The mobile app had to be a peer, not a viewer. Almost every CRM's mobile app is a reduced version of the web product — read records, update a status, maybe log a call. This client needed agents creating full listings with photos and video, capturing voice notes, and moving deal stages from a phone at the property. Where a product's app is a viewer, agents keep using paper and the whole system fails at the point it was meant to help.
They intended to sell the platform. The client wanted to license it to other brokerages, which means plans, usage limits, billing cycles, coupons, proration on upgrades and self-serve subscription management. You cannot resell someone else's SaaS product as your own.
The honest test: write down your five most-used workflows in full detail, then check how many survive contact with the product without modification. Four or five survive — buy it. Two or fewer — customisation cost approaches build cost and you own nothing at the end. This client scored badly enough that building was the cheaper five-year position.
We treated the dashboard and the app as two views onto the same data rather than two projects that talk to each other. One PostgreSQL schema, one Node.js API, one contract.
What we did: modelled properties, leads, owners and subscriptions in PostgreSQL before designing a single interface, with per-category detail tables hanging off a shared property record. The Node.js API was built against that schema and frozen as a contract early.
Alternative considered: design the dashboard first, build the API to serve it, then adapt for mobile. Faster to something demonstrable.
Why the alternative lost: two clients reading one API means the schema has to be the contract rather than a suggestion. An API shaped around the dashboard's needs forces the mobile app into workarounds, and workarounds are where the two clients start disagreeing about what a record means. Freezing the contract early also let the web and mobile tracks run in parallel without drifting.
Trade-off accepted: weeks of modelling work with nothing visible to the client. On a fixed-cost engagement that is real money spent on something with no demo value.
What we did: PostgreSQL with real constraints, and a separate detail table per property category hanging off the shared property record.
Alternative considered: a document store with flexible per-category shapes, which is the natural fit for heterogeneous records.
Why the alternative lost: the dominant risk here is two clients disagreeing about what is true. Relational constraints make a class of inconsistency impossible rather than merely unlikely, and property, lead and subscription records all have genuine referential relationships. Flexibility was needed on attributes, not on relationships.
Trade-off accepted: category changes on an existing record become a data-integrity problem rather than a shrug. That bill came due, and it is covered below.
What we did: one Flutter codebase shipping to both stores, roughly 108,000 lines across 439 files, organised feature-first into sixteen self-contained modules with their own data, domain and presentation layers.
Alternative considered: native iOS and Android.
Why the alternative lost: two native codebases drift. Not in the first month — in month fourteen, when a fix lands on one platform and not the other, and agents on different phones start seeing different behaviour. For a product where consistency is the entire value proposition, that drift is the thing you are trying to prevent.
Trade-off accepted: platform-specific work still needs native bridges. We wrote one for iOS speech transcription.
What we did: WebSocket delivery for the in-app notification centre, Firebase Cloud Messaging for push when the app is backgrounded or closed.
Alternative considered: push for everything, which is simpler.
Why the alternative lost: these are genuinely different delivery problems. An agent with the app open needs the assignment to appear without a refresh. An agent with the app closed needs the phone to buzz. Solving both with one mechanism compromises both.
Delivery ran across five phases over 8 to 20 weeks
Phase 1 — Schema and API. Properties, leads, owners and subscriptions modelled in PostgreSQL, with the Node.js API built against it and frozen as a contract.
Phase 2 — Web dashboard. Next.js and React for managers, back-office staff and administrators: bulk property entry, pipeline oversight, agent assignment, reporting, and the full subscription and billing surface. Razorpay checkout lives here, and this is where an account owner manages their plan.
Phase 3 — Flutter field app. Sixteen feature-first modules. Dio for networking with a refresh-token interceptor, a shared pagination session driving every list, and state kept deliberately close to the widgets that own it.
Phase 4 — Real-time and field tooling. WebSocket notifications with Firebase push. Then the things agents actually asked for: voice-dictated notes with on-device transcription, Google Places address lookup, and photo and video capture attached directly to a listing.
Phase 5 — Hardening and store submission. Auth tokens moved into iOS Keychain and Android Keystore with a silent migration for existing sessions. Verbose logging hard-disabled in release builds. App Transport Security locked to HTTPS. Build script guards that refuse to produce a store binary from non-production configuration.
That last phase is the one most projects skip, and it is why most projects get rejected on first submission.
Individually, a form and a billing page are solved problems. The real work was staying consistent across two clients.
The problem. The commercial model is a Razorpay subscription. Apple does not permit a third-party gateway for digital access inside an iOS app, and using in-app purchase would have split billing across two systems — Razorpay for web customers, Apple for iOS customers, with no single source of truth about who is subscribed to what.
How we solved it. Razorpay checkout stayed on the web dashboard, with one platform gate suppressing every purchase path inside the app behind a flag. A background poller reconciles subscription state after Razorpay's webhook lands.
Why it matters: this was designed in from the first architecture conversation rather than discovered during App Store review. That decision saved an entire submission cycle. If you are building a subscription product with an iOS app, this constraint should shape your commercial model before it shapes your code.
Outcome: one billing source of truth across three platforms.
The problem. Each property category writes to its own detail table. Changing a record's category after creation left the old rows orphaned — still attached, still returned by some queries, quietly wrong. This is the bill that came due from the relational decision above.
How we solved it. Every read path now keys attribute resolution off the record's current category rather than whichever detail row it finds first. The category picker locks once a record exists, backed by regression tests covering the exact case found in QA.
Why it matters: the instinct is to fix the display, because that is where the bug appears. The bug was in the data model, and a display fix would have left a landmine that surfaced eighteen months later in a report nobody could explain.
Outcome: zero orphaned detail rows after reclassification.
The problem. Registration verifies a phone by OTP, then conditionally an email, with the auth token issued only at the end. An app killed mid-flow left users verified enough to be rejected and not enough to proceed — a dead account that could neither log in nor register again.
How we solved it. Signup was rebuilt as a state machine that persists its stage, honours the backend's verification flag, and rehydrates on launch into exactly the step the user left, through to plan selection.
Why it matters: multi-stage signup flows that assume the app stays open are one of the most common causes of silent user loss in Indian mobile products, where mid-flow interruptions are routine.
Outcome: interrupted signups resume where they stopped.
The problem. Session and refresh tokens were sitting in plain preferences storage, readable from a device backup or a rooted handset. Fixing it naively — read from encrypted storage, find nothing, treat as logged out — would have signed out every existing user at once.
How we solved it. Reads check encrypted storage first and fall back to the legacy location, migrating the value and deleting the plaintext copy on first access. Shipped alongside disabled verbose logging in release builds.
Outcome: no plaintext tokens, no forced re-login.
Three of these four were found in a pre-submission audit rather than specified in the brief. Nobody writes "make sure tokens are not in plaintext" in a requirements document — it either gets caught before launch or it becomes an incident. When evaluating a development partner, ask what their pre-release security audit covers. If the answer is vague, the audit does not exist.
The clearest measure was behavioural rather than numerical. Within the first weeks after rollout the shared spreadsheets stopped being edited — not because anyone banned them, but because the app answered the same questions faster and agents stopped opening them.
Before | After | |
|---|---|---|
Lead ownership | Shared inbox, no rules | API-enforced single owner, visible to all |
Listings | Split across sheets, chats, photo folders | One category-aware record with media attached |
Field work | Desk-bound, re-entered later or lost | Created and edited on site, voice notes transcribed |
Reporting | Hours of manual counting | A search |
Commercial model | Service business | Licensable product with plans and metering |
16 modules delivered as one connected product — leads, properties, owners, groups, calendar, maintenance, notifications and billing.
4 property categories each with their own field set, validation and area semantics.
3 platforms live — web dashboard, iOS and Android, all reading one API and one schema.
Zero duplicate enquiries. The duplicate-contact complaints that prompted the project stopped.
Zero plaintext credentials. Tokens in Keychain and Keystore with silent migration, release logging hard-disabled.
The strategic outcome matters as much as the operational one. The client started with a service business and finished with a product they can license to other brokerages — plans, usage metering and Razorpay billing were built in from day one rather than retrofitted.
Anyone quoting before reviewing your workflows is guessing. What is useful is knowing what moves the number.
Cost drivers, roughly in order of impact:
Platform count. Web plus iOS plus Android is a different budget from web alone. Flutter reduces the gap; it does not close it.
Property category complexity. One category with a flat field set is straightforward. Four categories with distinct validation, area semantics and reclassification handling is materially more work.
Subscription billing. If you are only serving your own brokerage, skip it. If you intend to license the platform, plans, proration, coupons, metering and webhook reconciliation are a significant slice of scope.
Field capability depth. A mobile app that views records costs a fraction of one that creates listings with media, captures voice notes and transcribes them.
Real-time requirements. WebSocket plus push is more than either alone.
Integrations. Payment gateway, maps and places, speech transcription, portal feeds to 99acres or MagicBricks, telephony and IVR for call logging, WhatsApp Business API.
Data migration. Getting listings and contacts out of spreadsheets and chat threads is consistently harder than the sample rows suggest.
What reduces cost: documenting your existing workflows before kickoff, one empowered decision-maker, and phasing so leads and properties ship before calendar, maintenance and analytics.
Akoode's typical range for a build of this class: Setup meeting to discuss the cost - https://calendly.com/akhil-akoode/ak
This engagement ran fixed-cost, which suited a scope that was well-defined at the outset. Scope still forming is usually better served by a dedicated team or staff augmentation.
Gurgaon is a specific market and it puts specific pressure on a CRM. Our own office sits at Spaze iTech Park in Sector 49, so this is a market we work in as well as sell into.
Sector-level geography is not optional. Gurgaon inventory is discussed by sector and micro-market — Golf Course Road, Golf Course Extension, Dwarka Expressway, New Gurgaon, Sohna Road. A CRM that stores a free-text address makes "show me active listings in Sectors 65 to 70" impossible. Structured locality data should be in the schema from the start, not added later as tags.
Builder and project hierarchy. Primary-market work means leads attach to a project and a tower before they attach to a unit. Brokerages that do both primary and resale need a data model that holds both shapes without forcing one into the other.
Channel partner attribution. Much of Gurgaon primary sales runs through channel partners and sub-brokers. If commission splits and attribution are part of your business, they are part of your data model — retrofitting attribution onto a system that assumes one agent per lead is painful.
RERA record-keeping. Real estate agents operating in Haryana register with HARERA, and registered agents carry record-keeping and disclosure obligations. Requirements and timelines change, so confirm the current position with HARERA or your legal advisor rather than relying on any vendor's summary — but if compliance record-keeping matters to you, put it in the brief at the start. It is a schema decision, not a reporting feature bolted on later. This particular build did not include RERA-specific modules; the client's requirement was lead and property operations.
Portal feeds. Most Gurgaon brokerages publish to 99acres, MagicBricks and Housing. Whether your CRM pushes listings out to portals or merely stores what you posted manually is a scope decision worth making deliberately.
NRI and outstation buyer flows. A meaningful share of Gurgaon demand is remote. Video walkthroughs attached to listings, time-zone-aware follow-up scheduling and shareable property links matter more here than in a purely local market.
Lock category semantics in the schema review, not in QA. The reclassification bug was findable at design time. A written rule about what happens to a record when its category changes would have cost an hour then and saved a QA cycle later.
Build the pre-submission security audit into the plan, not the end of it. Three of the four hardest problems came out of that audit. Running it once, late, meant fixing four things under launch pressure. Running it twice — once mid-build — would have spread the load.
Sample migration data earlier and wider. Spreadsheets and chat threads are always messier than the first hundred rows suggest.
You can diagnose this yourself in an afternoon.
1. Count your duplicate contacts. Ask your agents how many times in the last month two of them called the same buyer. If nobody knows, that is the answer.
2. Ask a pipeline question and time it. "How many active commercial listings under two crore." If it takes more than a minute, your data is not queryable, whatever tool you think you have.
3. Watch one agent do one site visit. Note every moment they need information they cannot reach, and every note they write on paper. That list is your mobile requirement.
4. Check whether your categories fit one form. If your listing form has fields that are blank for most records, your data model is fighting your business — and agents are quietly skipping fields.
5. Decide now whether you will ever license this. Retrofitting subscription billing, usage metering and plan management onto a single-tenant internal tool is expensive. Deciding at the start costs almost nothing.
6. Run the five-workflow test. Write out your five most-used workflows in full and check them against any product you are considering. Four or five survive — buy it, and do not let anyone talk you out of that.
If steps one to six leave you certain either way, act on that certainty. If they leave you genuinely unsure whether to buy or build, that is the conversation worth having with someone who has done both.
Akoode Technologies is a software development company headquartered at Spaze iTech Park, Sector 49, Gurugram, with a US office in Oklahoma. We have delivered 180+ projects across 15+ industries for clients in India, the UK and the USA. Rated 4.9 on Google from 110 reviews and 5.0 on GoodFirms, and recognised by GoodFirms among the Top Artificial Intelligence Companies in India 2026.
Full technical breakdown of this build, including the architecture diagram: Real Estate CRM Platform case study
To discuss a CRM for your brokerage, book a technical consultation: calendly.com/akhil-akoode/ak — or send your requirement and someone responds within one business day. NDA signed before kickoff. IP is 100% yours from day one.
What is a custom real estate CRM? A CRM built around your brokerage's actual property types, lead ownership rules, commission structure and field workflows, rather than a general-purpose sales CRM configured with custom fields. It is the right choice when your property categories, attribution rules or commercial model do not fit what a product assumes.
Should we buy a real estate CRM or build one? Write out your five most-used workflows in complete detail and check how many survive contact with the product without modification. Four or five surviving means buy — it is cheaper and faster. Two or fewer means customisation cost will approach build cost and you will own nothing at the end.
How much does real estate CRM development cost in India? The main drivers are how many platforms you ship, how many property categories you model, whether subscription billing is in scope, how capable the field app needs to be, real-time requirements, integrations and data migration. Any figure quoted before a workflow review is a guess.
How long does it take to build a real estate CRM? It depends primarily on platform count and whether billing is in scope. Phasing so leads and properties ship before calendar, maintenance and analytics is usually the fastest route to something agents will actually use.
Can the mobile app work fully, or only view records? That is a scope decision and one of the most consequential ones. In this build the app creates listings with photos and video, logs visits, captures voice notes that transcribe to text, and moves deal stages. Where a mobile app is only a viewer, agents keep using paper and the system fails at the exact point it was meant to help.
How do you stop two agents working the same lead? By enforcing ownership in the API rather than by convention. A field labelled "assigned agent" that any agent can act around is not ownership. In this build the server refuses to let a second agent act on a lead someone else owns, and managers reassign from the dashboard.
Can a custom CRM handle different property types properly? Yes, and this is one of the strongest reasons to build. This platform models four categories — residential, commercial, plot and land — each with its own field set, validation and area semantics, so a plot listing never asks for a bedroom count. Forcing four categories into one flat form is where data quality collapses.
Can we integrate with 99acres, MagicBricks or Housing? Portal feeds are a common integration and should be scoped explicitly rather than assumed. Decide early whether the CRM pushes listings out to portals or only stores what you posted manually, because the two are very different builds.
Can we sell our CRM to other brokerages later? Only if it is built for that from the start. Plans, usage limits, billing cycles, coupons, proration and self-serve subscription management were in scope here from day one. Retrofitting them onto a single-tenant internal tool is expensive.
Why can't we take subscription payments inside the iOS app? Apple does not permit a third-party payment gateway for digital access inside an iOS app. On this build, Razorpay checkout stayed on the web dashboard with purchase paths suppressed in the app behind a platform gate, keeping one source of truth for billing across all three platforms. Designing for this early avoided a rejected submission.
Is our client data secure in a custom CRM? It depends on the build. On this one, auth tokens were moved into iOS Keychain and Android Keystore with a silent migration, verbose logging was hard-disabled in release builds, transport security was locked to HTTPS, and build scripts were guarded against producing store binaries from non-production configuration. Ask any development partner what their pre-release security audit covers.
Do you build real estate CRM platforms for brokerages in Gurgaon and Delhi NCR? Yes. Our India office is at Spaze iTech Park, Sector 49, Gurugram, and we work extensively with organisations across Gurgaon, Delhi and Noida. For Gurgaon brokerages specifically, sector-level locality data, builder and project hierarchy, and channel partner attribution are worth putting in the brief at the start.
Does the CRM handle RERA compliance? That depends entirely on scope, and it should be raised at the start because it is a schema decision rather than a reporting feature. This particular build did not include RERA-specific modules. Requirements vary by state and change over time, so confirm the current position with your state authority or legal advisor.
Can you migrate our existing data from spreadsheets and WhatsApp? Yes, and it should be scoped explicitly. Historical listings and contacts spread across sheets, chat threads and photo folders are consistently messier than the first hundred rows suggest. Sample broadly and early.
Who owns the code? With Akoode, intellectual property transfers to the client from day one, with an NDA signed before kickoff. Confirm this explicitly with any development partner — retained IP and perpetual licence-back clauses are common and change what you are actually buying.
Subscribe to the Akoode newsletter for carefully curated insights on AI, digital intelligence, and real-world innovation. Just perspectives that help you think, plan, and build better.