Real estate software looks simple from a distance: listings, a CRM for leads, some document uploads, maybe a portal for buyers and sellers. Most technical founders scope it like a content site with a database of properties. Then the first MLS data agreement lands on the desk, or a state regulator asks where earnest money sits, and the scope triples without a single new feature request.
The compliance tail in real estate is not a feature you can defer. Listing data usually isn't yours to keep once a contract ends. Disclosure documents carry state-mandated retention periods that start at different events depending on the document type. Fair housing law constrains what your search filters and ad targeting are even allowed to do. And any money that touches a transaction before closing has to sit in a trust account governed by rules that have nothing to do with your Stripe integration.
None of this shows up in a wireframe. All of it shows up in an audit, a licensing board complaint, or a lawsuit after the fact. The pattern is consistent across domains we've seen this in: the parts of the product that look boring in a demo are the parts that get a company fined.
Listings Are Licensed Data, Not Your Content
When a platform pulls listings from an MLS via IDX or RETS/RESO feeds, it isn't importing content, it's operating under a data license with contractual obligations attached. Broker attribution has to render on every listing. Status changes (active, pending, withdrawn, sold) have to propagate on a defined interval, typically measured in minutes, not on your next nightly sync. And when a listing is withdrawn, most MLS agreements require you to purge the syndicated copy within a fixed window, often 24 to 72 hours, not archive it as historical content.
A generic CMS treats a listing as a record you own and can keep indefinitely for SEO value. That instinct is the violation. Before writing the sync job, get the actual data license from the MLS or aggregator and turn its clauses into enforceable rules, not documentation:
- Sync interval matches the license's freshness requirement, not your infra budget
- Broker reciprocity rules determine which listings you're even allowed to display, not just source
- Attribution and disclaimer text renders on every listing view, generated from the feed's broker data, not hardcoded
- A withdrawn or sold status triggers an automatic purge job with a logged timestamp, so you can prove compliance if audited
Every Document Has a Retention Clock, and It Doesn't Start at Upload
Disclosures, leases, inspection reports, addenda, and closing packages each carry different state-mandated retention periods, commonly three to seven years depending on the state and the document class. The clock rarely starts at the moment a file lands in your storage bucket. A property disclosure's clock starts at close of escrow. A canceled offer's clock starts at cancellation. A terminated lease's clock starts at termination, not signing. A document store that only tracks created_at and deleted_at can't answer the question a regulator or a plaintiff's attorney will actually ask, which is when the retention obligation began and when it lapses.
This is the same category of problem we cover in our post on the document review problem generic legal software ignores: the document isn't a blob, it's a record with a lifecycle. A minimal schema that survives an audit looks like this:
create table transaction_documents (
id uuid primary key,
transaction_id uuid not null,
doc_type text not null, -- 'disclosure', 'lease', 'addendum', 'inspection'
retention_years int not null,
retention_trigger_event text not null, -- 'close_of_escrow', 'lease_termination'
trigger_event_at timestamptz,
purge_after timestamptz generated always as
(trigger_event_at + (retention_years || ' years')::interval) stored,
accessed_log jsonb default '[]'
);
Every state's retention rules differ and some overlap with federal recordkeeping requirements, so this table's retention_years should be a lookup keyed on jurisdiction and doc type, not a constant. Get the actual numbers from the brokerage's compliance officer or state real estate commission, not from a generic list found online, before this ships.
Fair Housing Rules Constrain the Product Surface, Not Just the Ad Copy
Fair housing compliance is usually treated as a content review problem: don't let agents write discriminatory listing descriptions. That's necessary but not sufficient. The rules also constrain the product itself. Ad platforms restrict audience targeting for housing ads by age, gender, and zip code proximity to protected demographics, which means a real estate platform's own ad-buying integration has to route through those restricted categories, not the platform's general-purpose ad tooling. Search filters that let a buyer screen by school ratings or crime statistics can function as a proxy for filtering by protected class, and several jurisdictions treat that as a fair housing exposure even when the filter itself looks neutral.
Free-text fields are the highest-risk surface. An agent typing a listing description or a CRM note field needs keyword screening against known fair housing violation terms before publish, not after a complaint. This is a moderation pipeline, not a legal disclaimer at the bottom of the page.
Trust and Earnest Money Accounts Aren't Revenue
Earnest money sitting in a trust account is someone else's money you are temporarily responsible for, and it has to be accounted for as a liability from the second it lands.
This is the same discipline we wrote about in reconciliation, ledgers, and why a float isn't money, applied to a different regulator. Most states require earnest money and other transaction funds to sit in a segregated broker trust account, tracked per-transaction, disbursed only on a defined trigger (closing, mutual release, or court order), and reconciled against the bank statement on a fixed cadence, often monthly. Commingling those funds with operating revenue is one of the more common ways a brokerage loses its license, and it's usually a software design failure, not a bookkeeping one: a single ledger table with a transaction_id column instead of a genuinely separate trust ledger with its own reconciliation report.
The fix isn't complicated engineering. It's a second, isolated ledger, a disbursement workflow gated on the specific trigger event for that transaction, and a monthly reconciliation report that ties every dollar in the trust account to a specific transaction and a specific state. If that reconciliation can't run automatically, it won't run at all, and that's the audit finding that shuts a brokerage down.
Agent and License Verification Isn't a One-Time Gate
Most platforms check a real estate license once, at signup, and never again. Licenses expire, lapse for continuing education non-compliance, or get suspended, and a platform that doesn't re-verify will happily let a delisted agent create listings, sign documents, or receive commission disbursements weeks after their license went inactive. Periodic re-verification against the state licensing board, gating specific actions (listing creation, e-signature authority, disbursement approval) on current license status, is the difference between a platform that's exposed and one that isn't. This matters more in states with reciprocal licensing across MLS boundaries, where an agent's authority to act can differ by county even when their license is valid statewide.
What to Build Versus What to Buy
The honest tradeoff here: don't build MLS feed aggregation, e-signature infrastructure, or identity verification from scratch. Those vendors carry certifications, legal liability, and edge-case handling that took them years to get right, and the switching cost of a bad in-house e-signature implementation shows up the first time a signed lease is challenged in court. Build the transaction logic, the retention rules, the trust ledger, and the license-gating yourself, because that's the part specific to how a given brokerage or state operates, and no vendor is going to encode your compliance rules correctly on your behalf.
We think about domain rules this way across every vertical we build in, not just real estate; see the sectors we ship into and how we scope this kind of build for the pattern. If a real estate platform is on the roadmap, start with what we build or look at how we approach a build from day one before the MLS agreement and the trust account rules get bolted onto an architecture that wasn't designed for either.
Frequently asked
Does a real estate platform need MLS certification before launch?
If it displays MLS-sourced listings via IDX, it typically needs to sign a data license or IDX agreement with the relevant MLS or a RESO-certified aggregator before going live. Certification requirements and fees vary by MLS, and displaying listings without one is a contract violation, not just a technical gap.
How long do real estate disclosures have to be retained?
It depends on the state and document type, commonly three to seven years, and the retention clock usually starts at an event like close of escrow or lease termination, not the upload date. Confirm exact periods with the brokerage's compliance officer or the state real estate commission before building retention logic.
Can earnest money be held in the same account as operating revenue?
No. Most states require earnest money and other transaction funds to sit in a segregated trust account, tracked per-transaction and reconciled separately from operating cash. Commingling trust funds with revenue is a common cause of license revocation and should be treated as a hard architectural boundary, not a bookkeeping convention.
What is IDX and why does it limit what I can build?
IDX (Internet Data Exchange) is the mechanism by which MLS listing data is licensed for display on third-party sites, and it comes with contractual limits on attribution, refresh frequency, and how long a withdrawn listing can remain visible. Building a listing feature without reading the IDX agreement usually means building something that has to be rebuilt.
Do fair housing rules affect search filters, not just listing text?
Yes. Filters that proxy for protected classes, such as school ratings or crime statistics used as neighborhood quality signals, can create fair housing exposure even when the filter itself doesn't reference a protected category directly. Ad targeting on external platforms is separately restricted by housing-specific rules that most general ad tooling doesn't enforce by default.