Merge

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.

Dashboard showing 22 entities created and 14 merges performed


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-12345 is 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" }
    ]
  }'

Schema list showing all five entity types with identity configuration

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:

Entity list showing all ingested and resolved 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\"}"
    }
  ]
}

Sarah Miller entity showing 3 merged source records from different systems

Robert Johnson entity showing merged sources including abbreviated name

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.

RE/MAX entity showing merged sources: "RE/MAX" and "Remax" unified

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   │
└─────────────────────────────────────────────────────────────────────┘

Reviews page showing resolution history and review queue

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.

Coldwell Banker entity showing 3 sources after force merge

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.

3-hop graph visualization from 742 Evergreen Terrace showing connected network

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

3-hop graph from Compass showing full agent→property→owner network

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."

Search results for "Kellar Willams" typo still finding 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 results for "RE/MAX" showing unified entity

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

Keller Williams merged entity showing 2 sources from different systems


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.

Start free All solutions