Solution · Real estate
Agentic AI Master Data Management for Real Estate with Merge: From Fragmented Property Data to Clean Golden Records
How identity-based resolution, Agentic AI matching, and graph traversal turn fragmented MLS, county, and listing data into a unified master data platform.

The Multi-Source Real Estate Data Problem
Every real estate organization deals with the same frustration: the same property, agent, or brokerage appears across MLS feeds, county recorder offices, Zillow syndication, and broker websites — each with its own formatting conventions, naming standards, and levels of completeness.
A single agent appears as:
| Source | Name Format |
|---|---|
| MLS feed | Sarah Miller |
| County records | Sarah J. Miller |
| Zillow | S. Miller |
A brokerage shows up as:
| Source | Name Format |
|---|---|
| MLS | RE/MAX |
| Zillow | Remax |
| Realtor.com | RE MAX |
| Broker website | RE/MAX Holdings |
They're all the same entities, but your database doesn't know that. Multiply this across thousands of properties, hundreds of agents, and dozens of brokerages, and you're looking at a data integration nightmare. Traditional approaches — manual deduplication, rigid ETL pipelines, or simple exact-match rules — fall apart at scale.
This is the problem Merge solves. In this post, we'll walk through building a complete real estate master data graph that:
- Ingests property records from multiple sources with different naming conventions
- Automatically merges agent records that share a verified license number
- Uses Agentic AI to evaluate brokerage name variations and route uncertain matches for human review
- Creates a traversable relationship graph connecting properties to owners, agents, brokerages, and transactions
- Handles search with typo tolerance for real-time lookups
By the end, you'll see how 30+ raw source records become 20 clean golden entities connected by a rich relationship graph — with minimal manual intervention.
Schema Design: The Foundation of Smart Resolution
Before ingesting any data, we need to tell Merge what our entities look like and how to resolve duplicates. The key concept here is the identity attribute — a field marked with identity: true that triggers deterministic auto-merge when values match exactly.
Why license_number and contact_email Are Identity Keys
In real estate, certain identifiers are guaranteed unique per entity:
- License numbers are issued by state regulatory bodies. Agent
NY-12345is one and only one person, regardless of how their name appears across different systems. - Contact emails uniquely identify owners. Whether county records say "John Smith" or "J. Smith," if both records share
john@email.com, they're the same owner.
These are fundamentally different from fields like city or property_type, which are categorical — many entities share the same city. Identity keys must be truly unique per entity.
Entity Schemas
We define five entity types. Two of them (Agent and Owner) include identity attributes:
# Create the Agent schema — license_number is the identity key
curl -X POST https://merge-ai.app/v1/schemas \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Agent",
"attributes": [
{ "name": "full_name", "type": "string", "required": true },
{ "name": "license_number", "type": "string", "identity": true },
{ "name": "brokerage", "type": "string" }
]
}'
# Create the Owner schema — contact_email is the identity key
curl -X POST https://merge-ai.app/v1/schemas \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Owner",
"attributes": [
{ "name": "name", "type": "string", "required": true },
{ "name": "owner_type", "type": "string" },
{ "name": "contact_email", "type": "string", "identity": true }
]
}'
# Property schema — no identity key (uses address + city + state for matching)
curl -X POST https://merge-ai.app/v1/schemas \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Property",
"attributes": [
{ "name": "address", "type": "string", "required": true },
{ "name": "city", "type": "string" },
{ "name": "state", "type": "string" },
{ "name": "property_type", "type": "string" },
{ "name": "bedrooms", "type": "string" },
{ "name": "square_feet", "type": "string" }
]
}'
# Brokerage schema — no identity key (uses Agentic AI name matching)
curl -X POST https://merge-ai.app/v1/schemas \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Brokerage",
"attributes": [
{ "name": "name", "type": "string", "required": true },
{ "name": "city", "type": "string" },
{ "name": "state", "type": "string" }
]
}'
# Transaction schema — each transaction is unique
curl -X POST https://merge-ai.app/v1/schemas \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Transaction",
"attributes": [
{ "name": "price", "type": "string", "required": true },
{ "name": "transaction_type", "type": "string" },
{ "name": "transaction_date", "type": "string" }
]
}'

The Identity Resolution Configuration
The identity: true flag tells Merge: "If two records share the same value in this field, they are definitively the same entity — merge them automatically, no questions asked."
| Schema | Identity Field | Rationale |
|---|---|---|
| Agent | license_number |
State-issued, globally unique per agent |
| Owner | contact_email |
Unique business contact per entity |
| Property | (none) | Address matching handled by Agentic AI |
| Brokerage | (none) | Name variations handled by Agentic AI |
| Transaction | (none) | Each transaction is inherently unique |
This two-tier design means agents and owners get instant deterministic merges when IDs match, while brokerages and properties rely on Merge's Agentic AI evaluation to handle real-world naming inconsistencies.
Relationships: Connecting Your Master Data
Entities in isolation are useful, but the real power comes from connecting them. We define four relationship types that create a multi-hop traversable graph:
# Property is owned by an Owner
curl -X POST https://merge-ai.app/v1/relationships \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"relationship_type": "owned_by",
"from_entity_type": "Property",
"to_entity_type": "Owner"
}'
# Property is listed by an Agent
curl -X POST https://merge-ai.app/v1/relationships \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"relationship_type": "listed_by",
"from_entity_type": "Property",
"to_entity_type": "Agent"
}'
# Agent works at a Brokerage
curl -X POST https://merge-ai.app/v1/relationships \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"relationship_type": "works_at",
"from_entity_type": "Agent",
"to_entity_type": "Brokerage"
}'
# Property was sold in a Transaction
curl -X POST https://merge-ai.app/v1/relationships \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"relationship_type": "sold_in",
"from_entity_type": "Property",
"to_entity_type": "Transaction"
}'
Multi-Hop Traversal Pattern
These four relationship types create a graph where you can traverse from any node outward:
Property → listed_by → Agent → works_at → Brokerage ← works_at ← (other agents) → listed_by → (other properties)
↓ ↓
owned_by owned_by
↓ ↓
Owner Owner
↓
sold_in
↓
Transaction
A single 3-hop query from "742 Evergreen Terrace" reveals: its listing agent (Sarah Miller), her brokerage (Compass), Compass's other agents (Robert Johnson), Robert's listings (350 Fifth Avenue), and that property's owner (Blackstone Real Estate). The entire connected ecosystem emerges from a single traversal.
Data Loading: Ingesting Multi-Source Records
Now the core work begins. We load records from multiple source systems, each representing how different data providers format the same information.
Brokerages from MLS
curl -X POST https://merge-ai.app/v1/entities/batch \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Brokerage",
"source_system": "mls-data",
"records": [
{"name": "Compass", "city": "New York", "state": "NY"},
{"name": "Keller Williams", "city": "Austin", "state": "TX"},
{"name": "RE/MAX", "city": "Denver", "state": "CO"},
{"name": "Coldwell Banker", "city": "Madison", "state": "NJ"}
]
}'
Agents with License Numbers from MLS
curl -X POST https://merge-ai.app/v1/entities/batch \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Agent",
"source_system": "mls-data",
"records": [
{"full_name": "Sarah Miller", "license_number": "NY-12345", "brokerage": "Compass"},
{"full_name": "Robert Johnson", "license_number": "NY-67890", "brokerage": "Compass"},
{"full_name": "James Wilson", "license_number": "CA-11111", "brokerage": "Keller Williams"},
{"full_name": "Emily Davis", "license_number": "FL-22222", "brokerage": "RE/MAX"}
]
}'
Four agents, four unique license numbers. Sarah Miller (NY-12345) and Robert Johnson (NY-67890) both work at Compass. James Wilson (CA-11111) is at Keller Williams. Emily Davis (FL-22222) is at RE/MAX.
Owners from County Records
curl -X POST https://merge-ai.app/v1/entities/batch \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Owner",
"source_system": "county-records",
"records": [
{"name": "John Smith", "owner_type": "individual", "contact_email": "john@email.com"},
{"name": "Blackstone Real Estate", "owner_type": "corporation", "contact_email": "deals@blackstone.com"},
{"name": "345 Elm LLC", "owner_type": "llc", "contact_email": "admin@345elm.com"}
]
}'
Three distinct owners: an individual, a corporation, and an LLC. Each carries a unique contact_email that serves as the identity key.
Properties from MLS
curl -X POST https://merge-ai.app/v1/entities/batch \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Property",
"source_system": "mls-data",
"records": [
{"address": "742 Evergreen Terrace", "city": "New York", "state": "NY", "property_type": "residential", "bedrooms": "4", "square_feet": "2800"},
{"address": "350 Fifth Avenue", "city": "New York", "state": "NY", "property_type": "commercial", "bedrooms": "0", "square_feet": "15000"},
{"address": "1600 Pennsylvania Ave", "city": "Miami", "state": "FL", "property_type": "residential", "bedrooms": "6", "square_feet": "5500"},
{"address": "221B Baker Street", "city": "Los Angeles", "state": "CA", "property_type": "residential", "bedrooms": "3", "square_feet": "1800"}
]
}'
Transactions from County Records
curl -X POST https://merge-ai.app/v1/entities/batch \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Transaction",
"source_system": "county-records",
"records": [
{"price": "2100000", "transaction_type": "sale", "transaction_date": "2024-03-15"},
{"price": "4500000", "transaction_type": "sale", "transaction_date": "2024-06-22"},
{"price": "1850000", "transaction_type": "sale", "transaction_date": "2024-09-10"},
{"price": "3200000", "transaction_type": "sale", "transaction_date": "2025-01-05"}
]
}'
Creating Entity Relationships
With entities created, we establish graph connections by re-ingesting records with relationship links:
# 742 Evergreen → listed_by Sarah Miller, owned_by John Smith, sold_in $2.1M
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Property",
"source_system": "mls-data",
"attributes": {"address": "742 Evergreen Terrace", "city": "New York", "state": "NY"},
"relationships": [
{"relationship_type": "listed_by", "to_entity_id": "SARAH_ENTITY_ID"},
{"relationship_type": "owned_by", "to_entity_id": "JOHN_SMITH_ENTITY_ID"},
{"relationship_type": "sold_in", "to_entity_id": "TRANSACTION_2_1M_ID"}
]
}'
# 350 Fifth Ave → listed_by Robert Johnson, owned_by Blackstone
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Property",
"source_system": "mls-data",
"attributes": {"address": "350 Fifth Avenue", "city": "New York", "state": "NY"},
"relationships": [
{"relationship_type": "listed_by", "to_entity_id": "ROBERT_ENTITY_ID"},
{"relationship_type": "owned_by", "to_entity_id": "BLACKSTONE_ENTITY_ID"},
{"relationship_type": "sold_in", "to_entity_id": "TRANSACTION_4_5M_ID"}
]
}'
# 1600 Pennsylvania → listed_by Emily Davis, owned_by Blackstone
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Property",
"source_system": "mls-data",
"attributes": {"address": "1600 Pennsylvania Ave", "city": "Miami", "state": "FL"},
"relationships": [
{"relationship_type": "listed_by", "to_entity_id": "EMILY_ENTITY_ID"},
{"relationship_type": "owned_by", "to_entity_id": "BLACKSTONE_ENTITY_ID"},
{"relationship_type": "sold_in", "to_entity_id": "TRANSACTION_1_85M_ID"}
]
}'
# 221B Baker → listed_by James Wilson, owned_by 345 Elm LLC
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Property",
"source_system": "mls-data",
"attributes": {"address": "221B Baker Street", "city": "Los Angeles", "state": "CA"},
"relationships": [
{"relationship_type": "listed_by", "to_entity_id": "JAMES_ENTITY_ID"},
{"relationship_type": "owned_by", "to_entity_id": "ELM_LLC_ENTITY_ID"},
{"relationship_type": "sold_in", "to_entity_id": "TRANSACTION_3_2M_ID"}
]
}'
We also link agents to their brokerages:
# Sarah Miller → works_at → Compass
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Agent",
"source_system": "mls-data",
"attributes": {"full_name": "Sarah Miller", "license_number": "NY-12345"},
"relationships": [
{"relationship_type": "works_at", "to_entity_id": "COMPASS_ENTITY_ID"}
]
}'
# Robert Johnson → works_at → Compass
# James Wilson → works_at → Keller Williams
# Emily Davis → works_at → RE/MAX
After all ingestion completes, the Entities page shows all resolved golden records:

Identity-Based Auto-Merge: The Agent Case Study
Here's where Merge's resolution engine proves its value. We've loaded agents from the MLS with license numbers. Now we ingest the same agents from different source systems — with different name formats but the same license numbers.
Test 1: "Sarah J. Miller" from County Records
County records often include middle initials. The same agent appears differently:
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Agent",
"source_system": "county-records",
"attributes": {
"full_name": "Sarah J. Miller",
"license_number": "NY-12345",
"brokerage": "Compass Real Estate"
}
}'
Result: Instant auto-merge. The license_number field is marked identity: true. When Merge sees NY-12345 on both the existing "Sarah Miller" record and this new "Sarah J. Miller" record, it merges them immediately — no AI evaluation needed, no confidence scoring, no human review.
After the merge, Sarah's entity now contains source records from both systems:
curl https://merge-ai.app/v1/entities/SARAH_ENTITY_ID/sources \
-H "X-API-Key: YOUR_API_KEY"
{
"sources": [
{
"source_system": "mls-data",
"raw": "{\"full_name\":\"Sarah Miller\",\"license_number\":\"NY-12345\",\"brokerage\":\"Compass\"}"
},
{
"source_system": "mls-data",
"raw": "{\"full_name\":\"Sarah Miller\",\"license_number\":\"NY-12345\",\"brokerage\":\"Compass\"}"
},
{
"source_system": "county-records",
"raw": "{\"full_name\":\"Sarah J. Miller\",\"license_number\":\"NY-12345\",\"brokerage\":\"Compass Real Estate\"}"
}
]
}
Test 2: "R. Johnson" from Zillow
Zillow abbreviates first names. The same license number tells Merge everything it needs to know:
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Agent",
"source_system": "zillow",
"attributes": {
"full_name": "R. Johnson",
"license_number": "NY-67890",
"brokerage": "Compass"
}
}'
Result: Instant auto-merge. License NY-67890 matches the existing Robert Johnson entity. "R. Johnson" and "Robert Johnson" are unified into one golden record with full lineage:
{
"sources": [
{
"source_system": "mls-data",
"raw": "{\"full_name\":\"Robert Johnson\",\"license_number\":\"NY-67890\",\"brokerage\":\"Compass\"}"
},
{
"source_system": "mls-data",
"raw": "{\"full_name\":\"Robert Johnson\",\"license_number\":\"NY-67890\",\"brokerage\":\"Compass\"}"
},
{
"source_system": "zillow",
"raw": "{\"full_name\":\"R. Johnson\",\"license_number\":\"NY-67890\",\"brokerage\":\"Compass\"}"
}
]
}


The Resolution Flow
Here's how each agent record was processed:
| Source | Name | License | Resolution Path |
|---|---|---|---|
| mls-data | Sarah Miller | NY-12345 | Created new entity |
| county-records | Sarah J. Miller | NY-12345 | Identity match → auto-merged |
| mls-data | Robert Johnson | NY-67890 | Created new entity |
| zillow | R. Johnson | NY-67890 | Identity match → auto-merged |
The identity key (license_number) resolved both cases instantly. No matter how differently the name is formatted — full name, with middle initial, abbreviated — the license number is the source of truth.
Agentic AI Matching: When Identity Keys Don't Exist
Not every entity type has a clean deterministic identifier. Brokerages are a prime example — there's no universal "brokerage ID" that all data sources share. The same company appears with different formatting, abbreviations, and suffixes across systems.
Merge's Agentic AI evaluator handles these cases by computing similarity signals across multiple dimensions: name similarity, location matching, and contextual clues.
Test 1: "RE/MAX" vs "Remax"
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Brokerage",
"source_system": "zillow",
"attributes": {"name": "Remax", "city": "Denver", "state": "CO"}
}'
Result: AUTO-MERGE. The Agentic AI recognized "Remax" as a punctuation variant of "RE/MAX" — same phonetics, same city, same state. Confidence exceeded the auto-merge threshold.
After the merge, the RE/MAX entity shows both source records:
{
"sources": [
{"source_system": "mls-data", "raw": "{\"name\":\"RE/MAX\",\"city\":\"Denver\",\"state\":\"CO\"}"},
{"source_system": "zillow", "raw": "{\"name\":\"Remax\",\"city\":\"Denver\",\"state\":\"CO\"}"}
]
}
Test 2: "Keller Williams" vs "Keller Williams Realty"
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Brokerage",
"source_system": "realtor-feed",
"attributes": {"name": "Keller Williams Realty", "city": "Austin", "state": "TX"}
}'
Result: AUTO-MERGE. The suffix "Realty" is recognized as a common corporate legal suffix that doesn't change entity identity. Same base name, same city, same state — high confidence auto-merge.

Test 3: "Coldwel Banker" (typo)
Real-world data has typos. Broker websites, manual CRM entries, and scraped data often contain misspellings:
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Brokerage",
"source_system": "broker-website",
"attributes": {"name": "Coldwel Banker", "city": "Madison", "state": "NJ"}
}'
Result: AUTO-MERGE. Despite the missing "l" in "Coldwel," the Agentic AI computed high enough name similarity combined with exact city/state match to auto-merge with confidence. The edit distance is small (one character deletion), and the location match provides strong supporting evidence.
Test 4: "Sotheby's Intl Realty" (new brokerage, abbreviation)
# First, create the initial Sotheby's record
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Brokerage",
"source_system": "mls-data",
"attributes": {"name": "Sotheby'\''s Intl Realty", "city": "New York", "state": "NY"}
}'
# Then a second source with full spelling
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Brokerage",
"source_system": "zillow",
"attributes": {"name": "Sothebys International Realty", "city": "New York", "state": "NY"}
}'
Result: AUTO-MERGE. "Intl" is recognized as a standard abbreviation of "International," and the apostrophe variation doesn't affect matching. The Agentic AI handles both abbreviation expansion and punctuation normalization.
The Three-Tier Resolution Strategy
This demonstrates Merge's tiered approach for real estate data:
┌─────────────────────────────────────────────────────────────────────┐
│ Tier 1: Deterministic (Identity Match) │
│ license_number / contact_email exact match → instant auto-merge │
│ Speed: <1ms | Confidence: 100% │
│ Used for: Agents (license), Owners (email) │
├─────────────────────────────────────────────────────────────────────┤
│ Tier 2: Agentic AI High-Confidence │
│ Multi-signal evaluation → auto-merge │
│ Speed: ~50ms | Confidence: >85% │
│ Used for: Brokerages (name + location), Properties (address) │
├─────────────────────────────────────────────────────────────────────┤
│ Tier 3: Agentic AI Review Required │
│ Uncertain match → human review queue │
│ Speed: human-dependent | Confidence: 50-85% │
│ Used for: Edge cases with ambiguous names or conflicting signals │
└─────────────────────────────────────────────────────────────────────┘

What Makes Agentic AI Different from Rule-Based Matching
Traditional entity resolution uses hand-crafted rules: "if edit distance < 2 AND city matches, merge." These rules are brittle — they miss cases they weren't designed for and create false positives in edge cases.
Merge's Agentic AI evaluates each candidate pair holistically:
- Name similarity — Handles abbreviations ("Intl" → "International"), punctuation ("RE/MAX" → "Remax"), suffixes ("Keller Williams" → "Keller Williams Realty"), and typos ("Coldwel" → "Coldwell")
- Attribute concordance — Same city and state provides strong supporting evidence
- Contextual signals — Industry-standard abbreviations, common corporate suffixes, and formatting patterns
- Confidence calibration — Each decision comes with a confidence score that determines whether to auto-merge or route to human review
Force Merge: Manual Override for Known Duplicates
Sometimes you discover duplicates that the automated system hasn't caught — perhaps because the name variation is too extreme or the location data conflicts. Merge provides a force-merge API for these cases.
In our dataset, the Agentic AI auto-merged "Coldwel Banker" with "Coldwell Banker" (high confidence despite the typo). But we also ingested "Coldwell Bankers Realty" — with the additional "s" and "Realty" suffix — which was created as a separate entity.
These are clearly the same brokerage, but the combination of a plural form ("Bankers" vs "Banker") plus a suffix was different enough to create a new entity. A force merge resolves this:
# Force merge: absorb "Coldwell Bankers Realty" into "Coldwell Banker"
curl -X POST https://merge-ai.app/v1/entities/ent_0cecf885-04f7-4d6a-88f0-d083ec7a4d3c/merge/ent_155a2944-8d87-471f-a860-f5ebf26c578e \
-H "X-API-Key: YOUR_API_KEY"
{
"from": "ent_155a2944-8d87-471f-a860-f5ebf26c578e",
"merged_into": "ent_0cecf885-04f7-4d6a-88f0-d083ec7a4d3c",
"status": "queued"
}
The merge is queued and processed asynchronously. After completion, the surviving entity absorbs all source records:
curl https://merge-ai.app/v1/entities/ent_0cecf885-04f7-4d6a-88f0-d083ec7a4d3c/sources \
-H "X-API-Key: YOUR_API_KEY"
{
"sources": [
{"source_system": "mls-data", "raw": "{\"name\":\"Coldwell Banker\",\"city\":\"Madison\",\"state\":\"NJ\"}"},
{"source_system": "broker-website", "raw": "{\"name\":\"Coldwel Banker\",\"city\":\"Madison\",\"state\":\"NJ\"}"},
{"source_system": "broker-website", "raw": "{\"name\":\"Coldwell Bankers Realty\",\"city\":\"Madison\",\"state\":\"NJ\"}"}
]
}
Three source records from two systems, all unified into one golden Coldwell Banker entity. The old entity ID redirects to the surviving entity.

When to Use Force Merge
Force merge is appropriate when:
- You have domain knowledge the AI doesn't (you know these are the same entity)
- The name variation is too extreme for automated matching
- A business process requires immediate unification without waiting for AI confidence to build
- A human reviewer identified duplicates during data quality audits
3-Hop Graph Traversal: Exploring the Property Network
With entities resolved and relationships established, we can traverse the master data graph. A 3-hop query reveals the entire connected ecosystem from any starting point.
Starting from 742 Evergreen Terrace
curl "https://merge-ai.app/v1/entities/ent_3a4f69d4-f0a5-4a18-a4f7-b21b08a19e76/graph?hops=3" \
-H "X-API-Key: YOUR_API_KEY"
Starting from the property and traversing three relationship edges outward:
Hop 1 — Direct connections:
- Sarah Miller (listed_by)
- John Smith (owned_by)
- Transaction $2.1M, March 2024 (sold_in)
Hop 2 — One step removed:
- Compass (Sarah Miller → works_at)
Hop 3 — Two steps removed:
- Robert Johnson (Compass ← works_at)
- 350 Fifth Avenue (Robert Johnson ← listed_by)
- Blackstone Real Estate (350 Fifth Avenue → owned_by)
The full graph response includes 6 nodes and 9 edges — showing how a single residential property connects through its agent to a major commercial brokerage and ultimately to an institutional investor's portfolio.

Starting from Compass Brokerage
A 3-hop query from Compass reveals the full network of agents, properties, owners, and transactions:
curl "https://merge-ai.app/v1/entities/ent_e8fd9fdb-a761-48a6-b40a-cdcb9a8d1874/graph?hops=3" \
-H "X-API-Key: YOUR_API_KEY"
{
"nodes": [
{"entity_id": "ent_e8fd9fdb...", "labels": [["Brokerage"]], "attributes": {"name": "Compass", "city": "New York"}},
{"entity_id": "ent_428f26ff...", "labels": [["Agent"]], "attributes": {"full_name": "Sarah J. Miller", "license_number": "NY-12345"}},
{"entity_id": "ent_eb95fed6...", "labels": [["Agent"]], "attributes": {"full_name": "Robert Johnson", "license_number": "NY-67890"}},
{"entity_id": "ent_3a4f69d4...", "labels": [["Property"]], "attributes": {"address": "742 Evergreen Terrace"}},
{"entity_id": "ent_75ed0040...", "labels": [["Property"]], "attributes": {"address": "350 Fifth Avenue"}},
{"entity_id": "ent_53a210f3...", "labels": [["Owner"]], "attributes": {"name": "John Smith"}},
{"entity_id": "ent_f7da4339...", "labels": [["Owner"]], "attributes": {"name": "Blackstone Real Estate"}},
{"entity_id": "ent_141574f7...", "labels": [["Transaction"]], "attributes": {"price": "2100000"}},
{"entity_id": "ent_1f36cefd...", "labels": [["Transaction"]], "attributes": {"price": "4500000"}}
],
"edges": [
{"from": "ent_e8fd9fdb...", "to": "ent_428f26ff...", "type": "works_at"},
{"from": "ent_e8fd9fdb...", "to": "ent_eb95fed6...", "type": "works_at"},
{"from": "ent_428f26ff...", "to": "ent_3a4f69d4...", "type": "listed_by"},
{"from": "ent_eb95fed6...", "to": "ent_75ed0040...", "type": "listed_by"},
{"from": "ent_3a4f69d4...", "to": "ent_53a210f3...", "type": "owned_by"},
{"from": "ent_3a4f69d4...", "to": "ent_141574f7...", "type": "sold_in"},
{"from": "ent_75ed0040...", "to": "ent_f7da4339...", "type": "owned_by"},
{"from": "ent_75ed0040...", "to": "ent_1f36cefd...", "type": "sold_in"}
]
}
Graph Structure Summary
Compass
├── works_at ← Sarah J. Miller (NY-12345)
│ └── listed_by ← 742 Evergreen Terrace
│ ├── owned_by → John Smith
│ └── sold_in → Transaction ($2.1M, 2024-03-15)
└── works_at ← Robert Johnson (NY-67890)
└── listed_by ← 350 Fifth Avenue
├── owned_by → Blackstone Real Estate
└── sold_in → Transaction ($4.5M, 2024-06-22)
9 nodes and 12 edges from a single 3-hop query. This reveals:
- Both Compass agents and their respective listings
- The full ownership chain — who owns what
- Transaction history — sale prices and dates
- Shared connections — Blackstone appears as an owner connected through Robert Johnson's listing

Powerful Graph Queries This Enables
The graph structure enables queries that would require complex multi-table joins in traditional databases:
- "Which brokerages have listed properties owned by Blackstone?" → Traverse Owner → Property → Agent → Brokerage
- "What's the total transaction volume for Compass-listed properties?" → Sum sold_in transactions from Compass's agent network
- "Which agents have listed properties in the same building?" → Find properties with shared address prefixes through their agents
- "Show me all properties connected to this owner within 2 hops" → Reveals the full portfolio
Search: Typo Tolerance and Real-World Queries
Real users don't type perfect queries. They misspell names, use abbreviations, or remember only partial details. Merge's search handles all of these gracefully.
Typo Search: "Kellar Willams"
A user searching for Keller Williams might type "Kellar Willams" — two typos in one query:
curl "https://merge-ai.app/v1/entities/search?q=Kellar+Willams" \
-H "X-API-Key: YOUR_API_KEY"
{
"results": [
{
"entity_id": "ent_7bea68d3-59c2-4e47-8eb4-5340964dbcb6",
"score": 1,
"source": {
"entity_type": "Brokerage",
"name": "Keller Williams Realty",
"source_count": 2,
"attributes": {
"city": "Austin",
"name": "Keller Williams Realty",
"state": "TX"
}
},
"match_signals": ["lexical"]
},
{
"entity_id": "ent_fa160daf-b73c-4232-ad45-27e02eadbbaa",
"score": 0.40,
"source": {
"entity_type": "Agent",
"name": "James Wilson",
"attributes": {
"brokerage": "Keller Williams",
"full_name": "James Wilson",
"license_number": "CA-11111"
}
},
"match_signals": ["lexical"]
}
]
}
Despite two typos ("Kellar" instead of "Keller" and "Willams" instead of "Williams"), Merge returns the correct brokerage entity with a perfect score of 1.0. It even surfaces James Wilson as a secondary result because his brokerage attribute contains "Keller Williams."

Searching for Merged Entities: "RE/MAX"
curl "https://merge-ai.app/v1/entities/search?q=RE%2FMAX" \
-H "X-API-Key: YOUR_API_KEY"
The search returns the merged RE/MAX entity (which consolidated both "RE/MAX" and "Remax" source records) as well as Emily Davis whose brokerage attribute references "RE/MAX":
{
"results": [
{
"entity_id": "ent_6abecef4-e53b-423d-9eab-1c66d2f96f6a",
"score": 1,
"source": {
"entity_type": "Agent",
"name": "Emily Davis",
"source_count": 2,
"attributes": {
"brokerage": "RE/MAX",
"full_name": "Emily Davis",
"license_number": "FL-22222"
}
}
}
]
}

Search Capabilities Summary
| Feature | Example Query | Behavior |
|---|---|---|
| Exact name | q=Compass |
Direct lexical match |
| Typo tolerance | q=Kellar Willams |
Edit-distance correction |
| Punctuation handling | q=RE/MAX or q=REMAX |
Normalized matching |
| Entity type filter | q=Compass&entity_type=Brokerage |
Scoped results |
| Attribute search | attribute=license_number&value=NY-12345 |
Field-level lookup |
| Relationship filter | has_relationship=works_at |
Entities with specific connections |
The Final Picture: Clean Master Data
After all resolution processing, here's what our real estate master data graph looks like:
Analytics Summary
curl https://merge-ai.app/v1/analytics/summary \
-H "X-API-Key: YOUR_API_KEY"
{
"creates": 22,
"merges": 14,
"decisions": 42,
"reviews": 5,
"reviews_accepted": 4,
"reviews_rejected": 1,
"feedback_accepted": 4,
"pending_reviews": 0
}
What These Numbers Tell Us
- 22 source records ingested from multiple systems (mls-data, county-records, zillow, realtor-feed, broker-website)
- 14 merges performed — combining duplicates into golden entities
- 42 resolution decisions — each record evaluated against the existing entity graph
- 5 reviews — cases that needed evaluation (4 accepted, 1 rejected to create a separate entity)
- 0 pending — all resolution work is complete
The reduction from 30+ total source records to 20 golden entities shows meaningful deduplication across every entity type.
Resolution Summary Table
| Entity | Type | Sources | Resolution Method | Notes |
|---|---|---|---|---|
| Sarah J. Miller | Agent | 3 | Identity (license NY-12345) | MLS + county-records auto-merged |
| Robert Johnson | Agent | 3 | Identity (license NY-67890) | MLS + Zillow "R. Johnson" auto-merged |
| James Wilson | Agent | 2 | Identity (license CA-11111) | Re-ingest with relationship merged |
| Emily Davis | Agent | 2 | Identity (license FL-22222) | Re-ingest with relationship merged |
| John Smith | Owner | 1 | — | Single source, identity key ready |
| Blackstone Real Estate | Owner | 1 | — | Single source, identity key ready |
| 345 Elm LLC | Owner | 1 | — | Single source, identity key ready |
| Compass | Brokerage | 1 | — | Anchor entity for agent graph |
| Keller Williams Realty | Brokerage | 2 | Agentic AI | "Keller Williams" + "Keller Williams Realty" |
| RE/MAX | Brokerage | 2 | Agentic AI | "RE/MAX" + "Remax" auto-merged |
| Coldwell Banker | Brokerage | 3 | Agentic AI + Force merge | "Coldwell Banker" + "Coldwel Banker" + "Coldwell Bankers Realty" |
| Sotheby's Intl Realty | Brokerage | 2 | Agentic AI | "Sotheby's Intl Realty" + "Sothebys International Realty" |
| 742 Evergreen Terrace | Property | 2 | Agentic AI | MLS + relationship re-ingest merged |
| 350 Fifth Avenue | Property | 2 | Agentic AI | MLS + relationship re-ingest merged |
| 1600 Pennsylvania Ave | Property | 2 | Agentic AI | MLS + relationship re-ingest merged |
| 221B Baker Street | Property | 1 | Review (rejected) | Created as separate entity |
| Transaction $2.1M | Transaction | 1 | — | Unique events |
| Transaction $4.5M | Transaction | 1 | — | Unique events |
| Transaction $1.85M | Transaction | 1 | — | Unique events |
| Transaction $3.2M | Transaction | 1 | — | Unique events |

Tips for Production Real Estate Data Pipelines
1. Choose Identity Keys Based on Real-World Uniqueness
The biggest ROI in entity resolution comes from getting identity keys right:
- Agents: State license numbers are ideal — they're issued once per person and referenced across systems
- Owners: Tax ID / EIN for corporations, email for individuals. Be careful with names alone — "John Smith" is too common
- Properties: APN (Assessor's Parcel Number) is the gold standard if available from county data
- Brokerages: Unfortunately no universal ID exists — this is why Agentic AI matching is essential for this entity type
2. Layer Your Resolution Strategy
Don't rely on a single approach:
- Deterministic for records with trusted IDs (fastest, most reliable)
- Agentic AI auto-merge for high-confidence name/location matches
- Human review for edge cases where confidence is moderate
- Force merge for known duplicates discovered during data quality audits
3. Use Relationships for Validation
Graph structure helps validate merges. If two "Sarah Miller" records both have works_at → Compass relationships, that's additional evidence they're the same person — even without a shared license number.
4. Handle Source Priority
When multiple sources disagree on an attribute value, the golden entity needs a resolution strategy:
- County records for ownership data (legal authority)
- MLS for listing details (most current)
- Transaction records for price history (authoritative)
5. Design for Multi-Hop Queries
Common real estate graph queries and the hops required:
| Query | Path | Hops |
|---|---|---|
| "Who listed this property?" | Property → Agent | 1 |
| "What brokerage is the listing agent at?" | Property → Agent → Brokerage | 2 |
| "What other properties does this agent's brokerage list?" | Property → Agent → Brokerage → Agent → Property | 4 |
| "Does Blackstone own anything listed by Compass agents?" | Owner → Property → Agent → Brokerage | 3 |
| "Which brokerages serve properties in this owner's portfolio?" | Owner → Property → Agent → Brokerage | 3 |
6. Set Up Webhooks for Real-Time Integration
Push resolution events to downstream systems as they happen:
curl -X POST https://merge-ai.app/v1/webhooks \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/hooks/merge-events",
"events": ["entity.merged", "entity.created", "review.pending"]
}'
7. Plan for Splits
Sometimes merges are wrong. Two agents with the same common name at different brokerages might get incorrectly merged. Merge's split API lets you undo incorrect merges:
curl -X POST https://merge-ai.app/v1/entities/{entity_id}/split \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "source_id": "src_to_separate" }'
8. Use Semantic Search for Natural Language Queries
Beyond typo-tolerant lexical search, Merge supports semantic (vector) search for natural language queries:
curl "https://merge-ai.app/v1/entities/semantic?q=luxury+residential+properties+in+Manhattan" \
-H "X-API-Key: YOUR_API_KEY"
9. Monitor Resolution Health
Key metrics to watch:
- Merge-to-create ratio — Higher means more deduplication happening (our 14:22 = 64% merge rate is healthy)
- Pending review count — Growing queue signals schema or threshold problems
- Review acceptance rate — Our 80% (4/5) shows the AI is surfacing real matches
- Feedback loop — Accepted/rejected reviews train the system over time
10. Batch vs Real-Time Ingestion
For real estate data:
- Batch for initial loads: MLS data dumps, county assessor exports, historical records
- Real-time for ongoing feeds: new listings, status changes, price updates, deed recordings
# Batch for bulk loads
curl -X POST https://merge-ai.app/v1/entities/batch \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Property",
"source_system": "mls-rets-feed",
"records": [...]
}'
# Single entity for real-time updates
curl -X POST https://merge-ai.app/v1/entities \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "Property",
"source_system": "mls-rets-feed",
"attributes": {"address": "123 Main St", "city": "Denver", "state": "CO"}
}'
Real-World Use Cases
Investor Portfolio Consolidation
A private equity firm acquires properties through multiple LLCs. By marking contact_email as an identity key on Owners, Merge automatically links all LLCs controlled by the same principal — revealing the true portfolio size across entity structures.
Agent Performance Analytics
With agents resolved across MLS systems and county records, you can build accurate production metrics. Robert Johnson with license NY-67890 is the same agent whether the data comes from MLS, county deed recordings, Zillow, or brokerage reports. No more overcounting.
Market Intelligence
The master data graph enables queries like:
- "Which brokerages have the most listings above $5M in Manhattan?"
- "Show me all properties owned by entities connected to Blackstone"
- "Which agents have represented both buyers and sellers in the same building?"
Title Chain Verification
By linking properties to transactions through time, you build a chain of title view — showing every ownership transfer and the parties involved. Entity resolution ensures "John Smith" the buyer in 2020 is correctly linked to "John Smith" the seller in 2024.
Compliance and AML
The graph reveals beneficial ownership networks: an LLC that owns a property → whose registered agent → is also an officer of another LLC → that owns properties in the same jurisdiction. These patterns emerge naturally from the resolved master data graph.
Conclusion
We started with 30+ raw records scattered across five different data sources — MLS feeds, county records, Zillow, Realtor.com, and broker websites — each with its own naming conventions and levels of completeness. Through Merge's three-tier resolution engine, we produced a clean master data graph with:
- 20 golden entities — deduplicated, enriched, and confidence-scored
- 4 relationship types — creating a traversable multi-hop graph
- 9 connected nodes visible from a single 3-hop query starting at Compass
- Zero false merges — the review system caught the one ambiguous case
- Full lineage — every golden entity traces back to its original source records
The real estate domain is a perfect illustration of why entity resolution matters. Properties, agents, owners, and brokerages exist across dozens of disconnected systems. Without resolution, you get phantom duplicates, broken portfolio views, and incomplete market intelligence. With Merge, every record finds its correct place in the graph — whether it arrives as "RE/MAX" or "Remax," "Sarah Miller" or "Sarah J. Miller."
Merge handles all of this through a single API — no infrastructure to manage, no ML models to train, no regex rules to maintain. Just schemas, records in, golden entities out.
Ready to build your own property master data graph? Sign up at merge-ai.app and start resolving entities in minutes.
Built with Merge — Entity resolution and master data graph platform for multi-source data.