Pull public commercial real estate listings from LoopNet and Crexi, then export one clean dataset for first-pass market scans, broker research, underwriting prep, CRM enrichment, or daily monitoring.
This repository is a public integration and workflow hub for the Commercial Real Estate Brokerage Intel Apify Actor. It is built for developers, CRE brokers, analysts, investors, and operators who want structured listing intelligence without manually rebuilding spreadsheets from multiple portals.
Commercial real estate teams often start research in two tabs: LoopNet and Crexi.
The manual workflow usually looks like this:
- Search a market on LoopNet.
- Repeat the same search on Crexi.
- Copy listings into a spreadsheet.
- Remove duplicate properties.
- Normalize price, rent, cap rate, square footage, and days on market.
- Find broker names and companies.
- Rebuild the same file tomorrow.
The actor turns that into one API call.
It is not trying to replace every enterprise CRE platform. It is designed for the first-pass market file: a clean, exportable dataset that helps you move from "what is listed?" to "which deals should I inspect?" faster.
| Need | Output |
|---|---|
| LoopNet listings data | Public LoopNet listing rows in a normalized schema |
| Crexi listings data | Public Crexi listing rows in the same schema |
| Commercial real estate API | JSON, CSV, Excel, Google Sheets, CRM, or database-ready records |
| Cross-platform deduplication | also_listed_on, also_listed_on_text, and stable dedup keys |
| Cap rate data API | Listed, implied, recomputed, or estimated cap-rate fields with provenance |
| Days-on-market data | days_on_market when the source exposes usable date signals |
| CRE broker leads | Broker name, company, phone, and email when publicly exposed |
| Daily monitoring | Emit only newly seen listings for a saved market scan |
| Transaction tracking | Detect removed, sold, leased, or changed listings across runs |
Open the actor:
apify.com/kazkn/commercial-real-estate-brokerage-intel
Use this input for a quick Austin market scan:
{
"city": "Austin",
"state": "TX",
"sourcesEnabled": ["loopnet", "crexi"],
"transactionTypes": ["sale"],
"assetClasses": ["office", "retail"],
"priceMin": 500000,
"priceMax": 5000000,
"maxResultsPerSource": 200,
"deduplicate": true,
"normalizeCapRate": true,
"includeListingDetails": false
}After the run finishes, export from Apify Storage as:
- CSV for Excel or Google Sheets
- JSON for API workflows
- XLSX for spreadsheet review
- API dataset items for apps, CRMs, or warehouses
For pure market scans, keep includeListingDetails disabled.
For broker lead research, enable it:
{
"city": "Dallas",
"state": "TX",
"sourcesEnabled": ["loopnet", "crexi"],
"transactionTypes": ["sale"],
"assetClasses": ["office", "industrial", "retail"],
"maxResultsPerSource": 1000,
"includeListingDetails": true
}Listing detail enrichment is best-effort and only fills broker phone/email when the source publicly exposes those fields.
This repo includes ready-to-use examples:
| File | Use case |
|---|---|
examples/01-curl-quickstart.sh |
Trigger a run from the terminal |
examples/02-python-market-scan.py |
Run a market scan and export CSV |
examples/03-node-daily-monitoring.mjs |
Schedule-style daily monitoring input |
examples/04-google-sheets-export.py |
Convert dataset items into a Sheets-ready CSV |
examples/05-broker-lead-list.py |
Build a broker outreach review file |
All examples read APIFY_TOKEN from the environment.
export APIFY_TOKEN=<YOUR_APIFY_TOKEN>Get your token from Apify Console.
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("kazkn/commercial-real-estate-brokerage-intel").call(run_input={
"city": "Dallas",
"state": "TX",
"sourcesEnabled": ["loopnet", "crexi"],
"transactionTypes": ["sale"],
"assetClasses": ["office", "retail", "industrial"],
"maxResultsPerSource": 500,
"deduplicate": True,
"normalizeCapRate": True,
"includeListingDetails": False
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(f"Fetched {len(items)} commercial real estate listings")import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor("kazkn/commercial-real-estate-brokerage-intel").call({
city: "Phoenix",
state: "AZ",
sourcesEnabled: ["loopnet", "crexi"],
transactionTypes: ["sale"],
assetClasses: ["office", "retail"],
maxResultsPerSource: 250,
deduplicate: true,
normalizeCapRate: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.slice(0, 5));Typical dataset columns include:
| Field | Meaning |
|---|---|
source |
loopnet or crexi |
source_listing_id |
Source-specific listing ID |
listing_url |
Public listing URL |
transaction_type |
sale or lease |
address_full |
Normalized address text |
city, state, zip |
Location fields when available |
asset_class |
Office, retail, industrial, multifamily, land, hotel, mixed-use, specialty |
asking_price_usd |
Sale asking price when exposed |
lease_rate / rent fields |
Lease rent fields when exposed by the source |
sqft |
Building or listing square footage when available |
cap_rate_listed |
Source-listed cap rate |
cap_rate_normalized |
Comparable cap rate field |
cap_rate_source |
Declared, recomputed, implied, or estimated |
noi_usd |
NOI value used for cap-rate calculations |
noi_source |
Declared, implied, or estimated |
days_on_market |
Days on market when a usable listing date exists |
broker_name |
Broker name when public |
broker_company |
Brokerage company when public |
broker_phone |
Broker phone when public |
broker_email |
Broker email when public |
also_listed_on |
Other source where the same property appears |
enrichment_status |
Whether a row is search-only, detail-enriched, or broker-limited |
See sample-data/example-output.json and sample-data/dallas-market-file-sample.csv for example rows.
The actor uses pay-per-event pricing on Apify:
| Event | Cost |
|---|---|
| Actor start | $0.05 per run |
| Result | $5.00 per 1,000 returned listings |
| Listing detail enrichment | $3.00 per 1,000 enriched listings |
Example run costs:
| Scenario | Approx. cost |
|---|---|
| 100 listings, no details | $0.55 |
| 1,000 listings, no details | $5.05 |
| 1,000 listings with details | $8.05 |
| 5,000 listings, no details | $25.05 |
Apify also gives new users free monthly platform credits, which are useful for testing small market scans.
Use the actor to create a quick market file for Dallas, Austin, Phoenix, Miami, Chicago, Los Angeles, or any other US city.
Recommended input:
{
"city": "Dallas",
"state": "TX",
"sourcesEnabled": ["loopnet", "crexi"],
"transactionTypes": ["sale"],
"assetClasses": ["office", "retail", "industrial"],
"maxResultsPerSource": 1000,
"deduplicate": true,
"normalizeCapRate": true
}Enable listing details to enrich the dataset with broker fields where public:
{
"city": "Austin",
"state": "TX",
"sourcesEnabled": ["loopnet", "crexi"],
"transactionTypes": ["sale"],
"assetClasses": ["office", "retail"],
"maxResultsPerSource": 500,
"includeListingDetails": true
}Use monitoringMode on an Apify schedule:
{
"city": "Phoenix",
"state": "AZ",
"sourcesEnabled": ["loopnet", "crexi"],
"transactionTypes": ["sale"],
"assetClasses": ["office", "industrial"],
"maxResultsPerSource": 1000,
"monitoringMode": true
}- How to deduplicate LoopNet and Crexi listings
- Build a daily CRE deal flow dashboard
- Broker lead workflow from public CRE listings
- Cost, data quality, and what this actor is not
Watch the demo: LoopNet + Crexi to one clean commercial real estate dataset.
- Commercial Real Estate Brokerage Intel on Apify
- Actor API documentation
- Apify platform
- LoopNet
- Crexi
- KazKN on Apify
No. It is better to position it as a lightweight first-pass market-file workflow. It helps you collect, normalize, export, and monitor public on-market listings from LoopNet and Crexi. It does not replace every proprietary research, comp, ownership, lease, or analytics feature in an enterprise CRE platform.
Only when the source publicly exposes them. The actor never invents broker contacts. Rows include broker fields and enrichment status so users can see what was available.
Yes. You can run it through Apify API, Python, Node.js, cURL, Apify schedules, webhooks, Make, Zapier, Google Sheets, Airtable, or your own backend.
Yes. Set sourcesEnabled to ["loopnet", "crexi"]. If both sources expose enough listings, maxResultsPerSource: 1000 can return up to 1,000 LoopNet rows plus 1,000 Crexi rows before deduplication.
No public listing source is perfectly complete. Some rows are search-only, some are detail-enriched, and some broker contact fields are blocked or not exposed. The actor is designed to return the maximum usable dataset without pretending unavailable fields exist.
- Open an issue in this repo for integration examples, feature requests, or documentation gaps.
- Run the actor on Apify: commercial-real-estate-brokerage-intel
Built by KazKN.
