Automating real estate lead research with a search API lets you programmatically find property listings, agent contact info, and market comps at scale instead of manually browsing dozens of sites. This tutorial walks you through building a pipeline that queries for properties in a target market, extracts listing details, and compiles agent leads into a structured dataset you can feed into your CRM or outreach tool.
Prerequisites
- Scavio API key (free 250 credits/mo at scavio.dev)
- Python 3.9+ or Node.js 18+
- Basic familiarity with REST APIs and JSON
Walkthrough
Step 1: Define your target market and search queries
Start by listing the geographic areas and property types you want to research. Build a set of search queries that combine location, property type, and intent keywords like "homes for sale", "commercial real estate listings", or "new construction". This gives you structured coverage of a market rather than random one-off searches.
queries = [
'homes for sale in Austin TX 2026',
'commercial real estate listings Austin TX',
'new construction homes Austin TX under 500k',
'Austin TX real estate agents top rated',
'Austin TX housing market data 2026',
]Step 2: Search for listings and agent data via API
Send each query to the Scavio search API. The response includes organic results with titles, URLs, and snippets that contain listing details and agent information. Use the num parameter to control how many results you pull per query.
import requests
API_KEY = 'your_scavio_api_key'
results = []
for query in queries:
resp = requests.post(
'https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'query': query, 'num': 20}
)
data = resp.json()
for item in data.get('organic', []):
results.append({
'query': query,
'title': item.get('title', ''),
'url': item.get('url', ''),
'snippet': item.get('snippet', ''),
})Step 3: Extract and deduplicate leads
Parse the results to extract agent names, brokerage info, and listing URLs. Deduplicate by URL so you do not store the same listing twice. Group leads by source domain to identify which platforms dominate your target market.
from urllib.parse import urlparse
seen_urls = set()
leads = []
for r in results:
if r['url'] in seen_urls:
continue
seen_urls.add(r['url'])
domain = urlparse(r['url']).netloc
leads.append({
'title': r['title'],
'url': r['url'],
'snippet': r['snippet'],
'source_domain': domain,
'query': r['query'],
})
print(f'Found {len(leads)} unique leads from {len(set(l["source_domain"] for l in leads))} domains')Step 4: Export leads to CSV for CRM import
Write the deduplicated leads to a CSV file that you can import directly into your CRM, outreach tool, or spreadsheet. Include all fields so your sales team has context on each lead without clicking through every URL.
import csv
with open('real_estate_leads.csv', 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=['title', 'url', 'snippet', 'source_domain', 'query'])
writer.writeheader()
writer.writerows(leads)
print(f'Exported {len(leads)} leads to real_estate_leads.csv')Python Example
import requests
import csv
from urllib.parse import urlparse
API_KEY = 'your_scavio_api_key'
queries = [
'homes for sale in Austin TX 2026',
'commercial real estate listings Austin TX',
'Austin TX real estate agents top rated',
]
results = []
for query in queries:
resp = requests.post(
'https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'query': query, 'num': 20}
)
data = resp.json()
for item in data.get('organic', []):
results.append({
'query': query,
'title': item.get('title', ''),
'url': item.get('url', ''),
'snippet': item.get('snippet', ''),
})
seen_urls = set()
leads = []
for r in results:
if r['url'] in seen_urls:
continue
seen_urls.add(r['url'])
domain = urlparse(r['url']).netloc
leads.append({
'title': r['title'],
'url': r['url'],
'snippet': r['snippet'],
'source_domain': domain,
'query': r['query'],
})
with open('real_estate_leads.csv', 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=['title', 'url', 'snippet', 'source_domain', 'query'])
writer.writeheader()
writer.writerows(leads)
print(f'Found {len(leads)} unique leads across {len(set(l["source_domain"] for l in leads))} domains')
print(f'Exported to real_estate_leads.csv')JavaScript Example
const fs = require('fs');
const API_KEY = 'your_scavio_api_key';
const queries = [
'homes for sale in Austin TX 2026',
'commercial real estate listings Austin TX',
'Austin TX real estate agents top rated',
];
async function main() {
const results = [];
for (const query of queries) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, num: 20 }),
});
const data = await resp.json();
for (const item of data.organic || []) {
results.push({
query,
title: item.title || '',
url: item.url || '',
snippet: item.snippet || '',
});
}
}
const seen = new Set();
const leads = [];
for (const r of results) {
if (seen.has(r.url)) continue;
seen.add(r.url);
const domain = new URL(r.url).hostname;
leads.push({ ...r, source_domain: domain });
}
const header = 'title,url,snippet,source_domain,query';
const rows = leads.map(l =>
[l.title, l.url, l.snippet, l.source_domain, l.query]
.map(v => `"${String(v).replace(/"/g, '""')}"`)
.join(',')
);
fs.writeFileSync('real_estate_leads.csv', [header, ...rows].join('\n'));
console.log(`Found ${leads.length} unique leads across ${new Set(leads.map(l => l.source_domain)).size} domains`);
console.log('Exported to real_estate_leads.csv');
}
main();Expected Output
Found 47 unique leads across 12 domains
Exported to real_estate_leads.csv