Realtor.com $0.9๐ฐ Listings, Prices & Agent Details
Pricing
from $0.90 / 1,000 results
Realtor.com $0.9๐ฐ Listings, Prices & Agent Details
From $0.9/1K. Extract property listings from realtor.com. Get comprehensive data, including prices, property details, agent contacts, coordinates, photos, and more. Supports for sale, rental, and recently sold listings across all US markets.
Pricing
from $0.90 / 1,000 results
Rating
5.0
(2)
Developer
Abot API
Maintained by CommunityActor stats
2
Bookmarked
15
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
Realtor.com Scraper: For Sale, Rental and Sold Listings Across the US
Realtor.com Scraper turns Realtor.com property search results into structured data. Search any US city or neighborhood, or paste a pre-filtered search URL, and get address, price, beds and baths, agent and brokerage contacts, MLS details, photos and GPS coordinates for sale, rental and recently sold listings. Schedule it to track a search over time with incremental mode, or export a summary of each listing (up to 50 per run by default, adjustable) straight into your apps.
Why This Scraper?
- Two ways to search. Pick a city and state and let the scraper build the search, or paste a realtor.com search URL you already filtered in a browser.
- Three listing types. For sale, for rent and recently sold, each with its own set of fields (sold price and date, or rental price ranges and unit listings).
- Deep filtering. Property type, beds, baths, price range, open house only and new construction only, applied server side.
- Agent, brokerage and MLS data. Names, emails, phones, office names, MLS ID and source for every listing that has them.
- Photos and tours. Up to 10 large format photos, total photo count, 3D tour links and a Google Street View URL when available.
- Resume built in. Checkpoint based resume that continues automatically after a restart, plus a separate option to continue one specific interrupted run by ID.
- Incremental mode for monitoring. Schedule the same search and get only new, updated or expired listings back, with minimal duplicate billing.
Use Cases
- Real estate agents and brokers: build a live feed of new and updated listings in the markets you serve.
- Investors and analysts: track price cuts, days on market and recently sold comps for a neighborhood or price band.
- Apartment and rental hunters: monitor rentals in a city with pet policy and unit level pricing.
- Market research and reporting: collect structured listing data across many cities for dashboards or spreadsheets.
- Lead generation tools: pull agent and brokerage contact details alongside the listings they represent.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
propertyId / listingId | "P100234567" / "L299887766" |
url | realtor.com link to the listing detail page |
listingType | "for_sale" (also "for_rent", "sold") |
status | "for_sale" |
address.street / city / stateCode / postalCode | "123 Main St" / "Portland" / "OR" / "97201" |
address.county | "Multnomah" |
coordinates.latitude / longitude | 45.5231 / -122.6765 (when the source returns them) |
price.value / price.display | 525000 / "$525,000" |
priceReducedAmount | 15000 (when the price has been cut) |
features.propertyType | "single_family" |
features.bedrooms / bathrooms | 3 / 2.5 |
features.sqft / lotSqft | 1850 / 5200 |
features.yearBuilt / garage | 2005 / 2 |
flags | {"isNewListing": true} (also price reduced, foreclosure, new construction, pending, contingent, coming soon, auction) |
agents | listing agent name, email, phone and office, one entry per agent |
brokerage | "Example Realty Group" |
mlsId / mlsName / mlsType | "MLS12345" / "RMLS" / source type |
photos / photoCount | up to 10 large photo URLs / total photo count |
hasMatterport / virtualTours | true / 3D and virtual tour links (when available) |
streetViewUrl | Google Street View link |
countyFips | "41051" |
openHouses | scheduled open house start date, end date and description, when present |
listDate / scrapedAt | ISO timestamps |
Rental listings (listingType: "for_rent") replace the single price.value with a price.min / price.max range, and add buildingName, petPolicy.cats / petPolicy.dogs, and a units array where each unit carries its own beds, baths, sqft, price and availableDate. Recently sold listings (listingType: "sold") add soldPrice and soldDate alongside the same address, features, brokerage and MLS fields as a for sale listing. In incremental mode, every row also gets changeType, changedFields, firstSeenAt and lastSeenAt, covered under How to Use below.
How to Use
- Pick a mode:
location(city and state, plus filters) orurl(paste realtor.com search URLs). - In location mode, add one or more cities or neighborhoods, set the listing type, and add any property type, beds, baths or price filters.
- Set Max Listings and Max Pages to control run size and cost, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
Search a city for sale with filters:
{"mode": "location","locations": [{ "city": "Denver", "state": "CO" }],"listingType": "for_sale","propertyType": "single_family","bedsMin": 3,"bathsMin": 2,"priceMin": 400000,"priceMax": 800000}
Paste a pre-filtered search URL:
{"mode": "url","urls": ["https://www.realtor.com/realestateandhomes-search/Portland_OR/type-single-family-home/beds-3"]}
Search rentals in a city:
{"mode": "location","locations": [{ "city": "Austin", "state": "TX" }],"listingType": "for_rent","bedsMin": 2,"priceMin": 1000,"priceMax": 2500}
Search recently sold properties:
{"mode": "location","locations": [{ "city": "San Francisco", "state": "CA" }],"listingType": "sold","propertyType": "condo"}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/realtor-com-scraper").call(run_input={"mode": "location","locations": [{"city": "Portland", "state": "OR"}],"listingType": "for_sale",})for listing in client.dataset(run["defaultDatasetId"]).iterate_items():print(listing["address"]["full"], listing["price"]["display"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/realtor-com-scraper').call({mode: 'location',locations: [{ city: 'Portland', state: 'OR' }],listingType: 'for_sale',});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Limits and filters
A page is up to 200 listings. Max Pages stops a location or URL after that many pages (0 = unlimited); Max Listings stops the whole run after that many listings across every location or URL (0 = unlimited). openHouseOnly only narrows for sale searches, it is ignored for rent and sold. newConstructionOnly narrows for sale and sold searches, it is ignored for rent. In URL mode, the Location and Filter fields above are ignored: property type, beds, baths, price, open house and new construction are instead parsed directly out of the pasted URL.
Resume and recurring updates
Three related but distinct fields:
-
resumeFromCheckpoint(default on) auto-continues this actor's own internal progress after a restart, no ID needed. This is what lets you click Resume on an interrupted run and pick up close to where it left off. -
resumeFromRunIdcontinues ONE specific interrupted run by ID. Paste a previous run ID or dataset ID from your account and listings it already collected are skipped, so this run returns only the delta. If the ID cannot be resolved to a run or dataset in your account, the run fails with a clear message instead of silently starting over. -
incrementalMode(default off) is for scheduling this actor against the SAME search repeatedly. Each listing is classified against the previous run:NEW, first time this listing has been seen.UPDATED, seen before, one or more fields changed (changedFieldslists which).UNCHANGED, identical to the last run. Suppressed and not billed unlessemitUnchangedis on.EXPIRED, a tombstone row for a listing that was tracked but is no longer found. Only produced after a run that scanned every configured search to its natural end withemitExpiredon; a resume, a block, or a Max Pages / Max Listings cap skips EXPIRED detection for that run and leaves the previous state as is.REAPPEARED, a listing comes back after an earlier complete scan withemitExpiredon found it missing and marked it expired.
stateKeynames or auto-derives which saved baseline a search is compared against; two differently configured searches never share one.emitUnchangedandemitExpiredare both off by default, so turning either on is what adds those extra billed rows. TurningincrementalModeon and off never changes existing output shape when it is off.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each listing, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify > Settings > Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where listing pages should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | location | location (city and filters) or url (paste search URLs). |
locations | array | none (prefill: [{"city": "Portland", "state": "OR"}]) | Cities or neighborhoods to search, location mode only. Each entry has city and a two letter state code. |
urls | array | none (prefill: one Portland search URL) | Full realtor.com search URLs, url mode only. |
listingType | string | for_sale | for_sale, for_rent, or sold. Location mode only, inferred from the URL in url mode. |
propertyType | string | any | any, single_family, condo, townhome, multi_family, mobile, farm, land. Location mode only. |
bedsMin | integer | none | Minimum bedrooms, 1 to 5. Location mode only. |
bathsMin | integer | none | Minimum bathrooms, 1 to 5. Location mode only. |
priceMin | integer | none | Minimum price in USD. Location mode only. |
priceMax | integer | none | Maximum price in USD. Location mode only. |
openHouseOnly | boolean | false | Only listings with a scheduled open house. For sale searches only. |
newConstructionOnly | boolean | false | Only new construction listings. For sale and sold searches only. |
maxListings | integer | 20 | Stop after this many listings, 0 for unlimited. |
maxPages | integer | 0 | Stop after this many pages per location or URL, 0 for unlimited. Each page is up to 200 listings. |
proxyConfiguration | object | {"useApifyProxy": true} | Connection settings. |
resumeFromCheckpoint | boolean | true | Auto-continue this actor's own progress after a restart, no ID needed. |
resumeFromRunId | string | none | Continue one interrupted run by pasting its run or dataset ID. |
incrementalMode | boolean | false | Classify each listing as NEW, UPDATED, UNCHANGED, REAPPEARED, or EXPIRED against the last run of the same search. |
stateKey | string | none (auto-derived from your search settings) | Names or shares an incremental mode baseline. |
emitUnchanged | boolean | false | Also return, and bill, listings identical to the last run. |
emitExpired | boolean | false | Also return, and bill, a tombstone row for listings no longer found. |
mcpConnectors | array | none | Send a summary of each listing to apps authorized under Integrations. |
notionParentPageUrl | string | none | Notion connector only, the page under which listing pages are created. |
maxNotifyListings | integer | 50 | Cap on listings exported to each connector per run. Does not affect the dataset. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"propertyId": "P100234567","listingId": "L299887766","url": "https://www.realtor.com/realestateandhomes-detail/123-Main-St_Portland_OR_97201_M12345-67890","listingType": "for_sale","status": "for_sale","address": {"street": "123 Main St","city": "Portland","state": "Oregon","stateCode": "OR","postalCode": "97201","county": "Multnomah","full": "123 Main St, Portland, OR, 97201"},"coordinates": {"latitude": 45.5231,"longitude": -122.6765},"price": {"value": 525000,"display": "$525,000"},"features": {"propertyType": "single_family","bedrooms": 3,"bathrooms": 2.5,"sqft": 1850,"lotSqft": 5200,"yearBuilt": 2005,"garage": 2},"flags": {"isNewListing": true},"agents": [{"name": "Jane Smith","email": "jane@example.com","type": "seller","office": "Example Realty Group","phone": "5035551234"}],"brokerage": "Example Realty Group","mlsId": "MLS12345","mlsName": "RMLS","streetViewUrl": "https://maps.googleapis.com/maps/api/streetview?...","hasMatterport": true,"photos": ["https://ap.rdcpix.com/example-photo-od-w480_h360_x2.jpg"],"photoCount": 32,"countyFips": "41051","listDate": "2026-03-15T10:00:00.000000Z","scrapedAt": "2026-03-23T10:30:00.000Z"}
Plan Requirement
The default proxy setting works out of the box, and the actor automatically switches to a backup connection if the primary one is refused. For large or frequent runs, the residential proxy group gives more headroom; pick it under Connection.
FAQ
How much does it cost?
You pay per listing returned. The Pricing tab shows the current rates. Use Max Listings and Max Pages to cap the cost of any run.
Is it legal to scrape Realtor.com?
This actor collects only publicly available real estate listing data. You are responsible for how you use it: follow Realtor.com's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Listing facts such as price and address are generally public, but photos and some agent or brokerage details may be subject to third-party rights.
Can I get only new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated, reappeared and (if enabled) expired listings, and unchanged ones are not returned or billed unless you turn emitUnchanged on.
What is the difference between Resume From Checkpoint, resumeFromRunId, and Incremental mode?
They solve three different problems. Resume From Checkpoint (on by default) auto-continues this actor's own progress after a restart of the same run, no ID needed. resumeFromRunId continues one specific past run by ID, useful when you manually split a very large search across multiple runs. Incremental mode is for a search you run repeatedly on a schedule; it remembers its own baseline and classifies each listing as new, updated, unchanged, reappeared or expired, without needing any ID at all.
Why did my run fail instead of returning zero listings?
Most problems, including no listings found for your search or a page that could not be loaded, end the run as succeeded with a status message and fewer (or zero) listings, rather than failing it. The run actually fails only when resumeFromRunId points at a run or dataset ID that cannot be found in your account, or when incrementalMode and resumeFromRunId are both set while that search already has saved incremental state (remove one of the two, or use a different stateKey, to resolve it).
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push a summary of each listing (up to maxNotifyListings, default 50) into Notion, Linear or Airtable.
๐ Want more Realtor data?
Pair this actor with these related scrapers from the same team:
| ๐ Realtor.ca From $1/1K. Scrape Realtor.ca property listings with prices, descriptions, images, agent... | ๐ View.com.au Scraper Scrape View.com.au properties for sale, rent and recently sold across Australia. Search... |
| ๐ Rent.com Scraper Extract rental listings from rent.com. Get comprehensive data including monthly rent... | ๐ Propertyfinder UAE From $0.8/1K. Extract property listings from propertyfinder.ae at scale. Get... |
| ๐ OnTheMarket Scraper Scrape onthemarket.com for-sale, to-rent and new-homes listings with 85+ fields: price... | ๐งฉ Zillow Scraper Scrape zillow.com properties for sale, for rent and recently sold across the US: price... |
๐ Browse all abotapi scrapers
๐ฌ Support & custom scrapers
- ๐ Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- ๐ ๏ธ Need another site, extra fields or a private build? Email abotapi@proton.me or message Telegram @abotapi.
- โญ Enjoying it? A quick review on the actor page helps other users find it.