# Realtor.com Scraper: Homes for Sale, Rent & Sold (`nice_dev/realtor-listings-scraper`) Actor

Realtor.com scraper for US homes for sale, for rent and sold, by city, ZIP code, county or URL: price, beds, baths, sqft, photos, description and the listing agent's name, email and phone. 40+ filters and monitoring of new listings. Export JSON, CSV or Excel.

- **URL**: https://apify.com/nice_dev/realtor-listings-scraper.md
- **Developed by:** [Nice Dev](https://apify.com/nice_dev) (community)
- **Categories:** Real estate, Lead generation, MCP servers
- **Features:** Limited permissions
- **Stats:** 4 total users, 2 monthly users, 98.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.42 / 1,000 listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 🏠 What is Realtor.com Scraper?

**Realtor.com Scraper** extracts **property listings from [Realtor.com](https://www.realtor.com)**: **price, beds, baths, square footage, the full description, every photo, and the listing agent's name, email and phone**, for any US city, ZIP code, county or state. It works as a **Realtor.com API alternative**: run it on a schedule, call it from your code, or plug it into Make, Zapier or n8n.

Type a **location** (`Austin, TX`), click **Start**, and download the listings in JSON, CSV or Excel. No login, nothing to set up, and it is **fast: about 1,000 listings in 10 seconds**. Homes for sale, for rent, sold, pending, coming soon, off market and builder plans to be built, with 31 filters and an optional detail pass that adds price history, tax history, schools, flood and fire risk and value estimates — plus two options sold apart: the property's **building permit history** (with a roof-permit flag) and **how many people viewed the listing**.

### 📋 What data can you extract from Realtor.com?

One item per listing, 165 fields:

| Category | What you get |
| --- | --- |
| 🏷️ **Listing** | Realtor.com id, MLS number, link, status (for sale, for rent, sold, pending, coming soon, off market, ready to build), who published it (an agent, a builder, a rental company), badges such as "new listing" or "price reduced" |
| 💰 **Price** | asking price, price per square foot, last price cut and its date, last sale price and date — `460000` USD, `285` per sq ft |
| 🏠 **The home** | property type, beds, baths, living area, lot size, year built, stories, garage spaces, HOA fee — 3 beds, 2.5 baths, 1,612 sq ft |
| 📍 **Location** | street address, city, state, ZIP code, county, neighborhood, latitude and longitude, Street View link |
| 📝 **Text and photos** | the agent's full description, feature lists (appliances, interior…), every photo, virtual tour, open houses, pet policy |
| 📇 **Agent and office** | listing agent's name, email, phone numbers, photo and website, office with its website, broker, MLS board — `(512) 637-8277` |
| 🕒 **Dates** | date listed, last update, days on market — what the date filters read |
| 📈 **History and estimates** | **detail** — price history, tax history, value estimates with their past and a 12-month forecast, mortgage estimate, monthly rent estimate with its range |
| 🏫 **Schools and risk** | **detail** — assigned schools with their rating, FEMA flood zone, flood, fire and noise scores |
| 👀 **Demand and permits** | **options** — how many people viewed, clicked and enquired, per period (`includeViewStats`); building permit history and a roof-permit flag (`includePermitHistory`) |

Every field, with an example, is listed in the **Output** section below.

Fields marked **detail** are filled when **Extract details** is on (read 25 listings per extra request, charged as its own event); fields marked **options** only when their option is on, each charged for what it delivers. Everything else — description, photos and the agent's contact details included — comes with the search results.

### ✅ Why use Realtor.com Listings Scraper?

- 🚀 **Fast**: about 1,000 listings in 10 seconds, 5 requests.
- 🏠 **Type the city, not a URL**: `Austin, TX`, `78704`, `Travis County` or `Texas` — or paste a Realtor.com search URL and its filters are read.
- 🎛️ **31 filters**: price, beds, baths, living area, lot, year built, garage, HOA fee, radius, property type, foreclosures, new construction, open houses, virtual tours, no pending sales, MLS listings only, pets — 27 of them applied by the site itself, so a filtered search costs less, not more.
- 📈 **More than the listing card**: price and tax history, school ratings, flood / fire / noise scores, value estimates with a 12-month forecast. On top, two options: the **building permit history** of the property (type of work, project, date, status) with a `hasRoofPermit` flag that spots roofing jobs at a glance — the list roofers, remodelers and insurers look for — and **how many people viewed, saved and enquired** about the listing over the last days. You pay for them only when they are delivered: a property with no permit on record, or a brand-new listing with no view count yet, costs nothing extra.
- 📇 **The listing agent comes with the listing**: name, email, phone, photo, office and broker, with no separate agent scraper to buy.
- 🔍 **Past the site's 10,000-result cap**: a search bigger than that is split into price bands (sold homes: sale-date ranges) on its own.
- 🔔 **Monitoring built in**: tick **Only new listings**, schedule the Actor, and each run returns (and charges) only what it has never delivered before.
- 🔌 API, scheduling, integrations (Make, Zapier, n8n, Google Sheets…), and JSON/CSV/Excel export via the Apify platform.

### 🚀 How to scrape Realtor.com

1. Create a free Apify account.
2. Open **Realtor.com Listings Scraper** and type a **Location** (e.g. `Austin, TX`).
3. Or paste your own Realtor.com URLs into **Start URLs**: search results pages, sold pages, rental pages, or single listing pages.
4. Pick a **Listing status** (for sale, for rent, sold, pending, coming soon, off market, ready to build), set the filters you need and **Max listings** (100 by default, 0 = no limit), then click **Start**.
5. Download the dataset in JSON, CSV, Excel or via API.

### 💰 How much does it cost to scrape Realtor.com?

This Actor uses **pay per event** pricing: **$0.45 per 1,000 listings** — plus **$0.01 per run start** ($1 per 100 runs). Listings read with **Extract details** on cost **$0.69 per 1,000** instead, the extra requests included. Two options come on top, charged only for what they deliver: **building permits, $1.79 per 1,000 permit rows** (3 permits on a property = 3 rows; none = nothing) and **view statistics, $0.89 per 1,000 listings** that have them; turning either on reads the detail page, so the listing is charged as a listing with details. A single listing page pasted into `startUrls` is always read in full and costs the same. Higher Apify plans pay less per listing: $0.44 (Bronze), $0.43 (Silver) and $0.42 (Gold) per 1,000 — with details $0.68, $0.67 and $0.66; permit rows $1.78, $1.77 and $1.76; view statistics $0.88, $0.87 and $0.86. The Actor's own filters (listing date, excluded keywords, agent phone) are applied to every listing it reads, kept or not: **$0.04 per 1,000 listings checked** (`filter-check`), $0.03 on Bronze, $0.02 on Silver and $0.01 on Gold; a run without them pays nothing for it. Example: 20,000 listings ≈ $9.01; a daily monitor of 300 new listings ≈ $0.15 a day. Platform usage (compute, proxy) is included in the price.

### ⚙️ Input

```json
{
    "location": "Austin, TX",
    "listingStatus": "for_sale",
    "maxItems": 200
}
```

Several locations, a cap per search, houses in a price range, only the ones not delivered before:

```json
{
    "locations": ["Austin, TX", "78704", "Dallas, TX"],
    "propertyType": ["single_family"],
    "minPrice": 300000,
    "maxPrice": 600000,
    "minBedrooms": 3,
    "maxItemsPerQuery": 500,
    "onlyNew": true,
    "stateKey": "austin-houses"
}
```

Or with your own URLs:

```json
{
    "startUrls": [
        { "url": "https://www.realtor.com/realestateandhomes-search/Austin_TX/beds-3/price-300000-600000" },
        { "url": "https://www.realtor.com/realestateandhomes-detail/7704-Fenton-Cv_Austin_TX_78736_M73634-37439" }
    ],
    "maxItems": 500
}
```

Give at least one place (`location` or `locations`) or one URL (`startUrls`). With none, the Actor runs an example instead of stopping — a search in Austin, TX, at most 20 listings — and says so in the log.

| Field                                                                                                    | Notes                                                                                                                                                                              |
| --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `location`, `locations`                                                                                     | City (`Austin, TX`), ZIP code (`78704`), county or state (`Texas`); `locations` adds more places.                                                                                    |
| `query`, `searchQueries`                                                                                    | Keyword matched against the listing text (`pool`, `waterfront`). Every keyword is searched in every location (max 500 searches per run).                                              |
| `startUrls`                                                                                                 | Realtor.com search, sold or rental pages (place, price, beds, baths, sqft, lot size, home age, days on market, HOA, garage, type, radius, listing switches, sort and page are read from the URL; features, keywords and price-reduced filters are refused by name) or single listing pages.                                                |
| `listingStatus`                                                                                             | `for_sale`, `for_rent`, `sold`, `pending`, `coming_soon`, `off_market` (listings that expired without a sale or a rental) or `ready_to_build` (plans of homes a builder will build).                                                                                                                          |
| `propertyType`                                                                                              | `single_family`, `condos`, `townhomes`, `multi_family`, `land`, `mobile`, `farm` — several at once.                                                                                  |
| `minPrice`, `maxPrice`, `minBedrooms`, `maxBedrooms`, `minBathrooms`, `maxBathrooms`                        | Price in US dollars (the monthly rent for rentals); half bathrooms count as 0.5.                                                                                                   |
| `minSqft`, `maxSqft`, `minLotSqft`, `maxLotSqft`, `minYearBuilt`, `maxYearBuilt`, `minGarage`, `maxHoaFee`  | Living area and lot in square feet, year built, garage spaces, monthly HOA fee.                                                                                                      |
| `radiusMiles`, `sortBy`, `soldWithinDays`                                                                   | Widen the search around the location (`5`); order the results (`list_date:desc`, also by price cut, open house, lot size, year built, full bathrooms, sold price for sold listings, move-in day for rentals); for sold listings, how far back to go.                                                              |
| `foreclosureOnly`, `newConstructionOnly`, `openHousesOnly`, `virtualTourOnly`, `noHoaFeeOnly`, `excludePending`, `mlsOnly`, `petsAllowed` | Switches applied by the site; `excludePending` leaves out the homes for sale already under contract (from 1 in 7 to 1 in 3, depending on the city); `mlsOnly` keeps the listings an MLS publishes (no builder plans, no apartments posted by rental companies); `petsAllowed` (`cats`, `dogs`) only applies to rentals.                                                                                                |
| `priceReducedWithinDays`, `priceReduced` | Only listings whose price dropped in the last N days, or ever (`priceReducedWithinDays` wins when both are set). Applied by the site. |
| `openHouseWithinDays`, `openHouseFrom`, `openHouseTo` | Only listings with an open house in the next N days (today included), or between two days (`2026-11-14`, `2026-11-15`, that last day whole). Not together. Applied by the site. |
| `has3DTour`, `withPhotoOnly` | Only listings with a 3D tour or a virtual tour; only listings with at least one photo. Applied by the site. |
| `tags`, `features` | Only listings that carry all the site tags you give: type any tag of the site in `tags` (`cul_de_sac`, `swimming_pool`) or pick from the list in `features`. Applied by the site. |
| `seniorCommunity` | `any`, `only` or `hide` for the 55+ communities. Applied by the site. |
| `mlsListingId` | One listing by the number its MLS gave it (`2427357`); give its place too. Applied by the site. |
| `moveInBy`, `rentSpecials`, `applyNow`, `builderPromotions` | Rentals available by a day (`2026-12-31`), rentals with a special offer, rentals you can apply for online (all three for **For rent** only); homes for sale and builder plans with a builder promotion. Applied by the site. |
| `soldAfter`, `soldBefore` | For sold listings, the first and last sale day (`2026-10-01`, `2026-10-31`, both included); with `soldWithinDays` the later start is used. Applied by the site. |
| `boundingBox`, `polygon`, `centerPoint`, `mapAreas` | Only listings inside an area of the map: a box (min / max latitude and longitude), a polygon (corners written longitude first, then latitude), a circle (a point and a radius in miles), or up to 20 such areas in `mapAreas` (one search each). With or without a location. Applied by the site. |
| `street` | Only listings on a street (`Congress Ave`) or at an address (`805 Congress Ave`). With or without a location. Applied by the site. |
| `agentName`, `officeName` | Only listings of one selling agent or of one office, by the name the site writes (`Keller Williams Realty`). An office needs a place (a location, a map area or a street). Applied by the site. |
| `minElementarySchoolRating`, `minMiddleSchoolRating`, `minHighSchoolRating`, `schoolDistrict` | Only homes served by schools rated at least this (1 to 10, 0 = off), or in one school district, by its exact name on the site (`Austin Independent School District`). Applied by the site. |
| `minSoldPrice`, `maxSoldPrice` | For sold listings, the price they sold for, in US dollars, both bounds included. States that do not publish sale prices return nothing. Applied by the site. |
| `commuteFrom`, `commuteMinutes`, `commuteMode` | Only homes within 10 to 60 minutes of a point, by car or on foot. The point is written latitude,longitude (`30.2672,-97.7431`); the minutes and the way are ignored without it. Applied by the site. |
| `floodRisk`, `fireRisk`, `windRisk`, `heatRisk`, `airRisk` | Only homes whose risk is exactly the level you pick (minimal, moderate or severe), not "at most". Any = no filter. Applied by the site. |
| `auctionOnly`, `shortSaleOnly`, `fractionalOwnershipOnly`, `matterportOnly`, `builderSpecHomesOnly`, `noPetsAllowed` | Only auctions; only short sales; only homes sold in shares; only listings with a Matterport 3D scan; only builder spec homes (for sale); only rentals that take no pets (for rent, not together with petsAllowed). Applied by the site. |
| `excludePropertyIds`, `excludePropertyTypes` | Leave out listings by the id of a row (`9954799904`, up to 500) or whole property types (land, mobile). Not together with `propertyType`. Applied by the site. |
| `extractDetails`                                                                                            | Add price and tax history, schools, risk scores and value estimates (read 25 listings per extra request, charged as its own event). Off by default.                  |
| `includeFloorplans`, `includeSchoolScores` | Free, off by default, each needs `extractDetails`: the floor plans of the listing; the math and reading test results of each nearby school (a heavier answer, about 13 KB more per listing). |
| `includeNearbyPlaces`, `nearbyPlaceCategories`, `nearbyPlacesRadiusMiles`, `nearbyPlacesPerCategory` | Free, off by default, needs `extractDetails`: the shops and services around each listing, nearest first. Pick the categories (restaurants, grocery stores, coffee and tea by default; also cafes, bars, parks, gyms, fitness, health, pharmacies, banks, arts, beauty and spas, hotels, playgrounds, child care, convenience and hardware stores), the radius (1 to 25 miles, 2 by default) and how many places per category (1 to 10, 5 by default). The three settings do nothing without the box. |
| `includePermitHistory`, `includeViewStats`                                                                  | Options, off by default: the building permits filed on the property with a roof-permit flag (charged per permit row), and the view / save / enquiry counts per period (charged per listing that has them). Either one turns `extractDetails` on. |
| `countOnly` | Free, off by default: only count how many listings each search has, without reading any. One number per search and one for the whole run, in the SEARCH_COUNTS record of the key-value store and in the log; the dataset stays empty and the run costs its start only. `maxItems`, `extractDetails`, the options, `postedAfter`, `postedBefore`, `excludeKeywords`, `requirePhone` and `onlyNew` are not used. |
| `maxItems`, `maxItemsPerQuery`                                                                              | Stop after this many listings for the whole run (`0` = unlimited); cap for EACH search (location × keyword, or search URL).                                                             |
| `postedAfter`, `postedBefore`                                                                               | Listing date range: `2026-09-01`, or a period before now (`7 days`, `2 weeks`, `1 month`, `24 hours`).                                                                                |
| `excludeKeywords`, `requirePhone`                                                                           | Drop listings whose address, city or description contains one of these WHOLE words (case and accents ignored: `pool` drops "Pool and spa" but keeps "Liverpool Rd"); or whose agent has no phone number.                                          |
| `onlyNew`, `stateKey`, `resetState`                                                                         | Monitoring: only the listings never delivered under this memory key; `resetState` forgets the memory.                                                                                 |
| Advanced                                                                                                    | `proxyConfiguration` (Apify proxy by default, included in the price; the residential proxy is not available), `maxConcurrency`, `maxRequestsPerMinute`, `maxRequestRetries`, `debugLog`. |

### 📦 Output

One item, shortened to the fields a search result carries (the **detail** fields are cut here):

```json
{
    "id": "7363437439",
    "listingId": "2816017",
    "url": "https://www.realtor.com/realestateandhomes-detail/7704-Fenton-Cv_Austin_TX_78736_M73634-37439",
    "status": "for_sale",
    "mlsStatus": "Active",
    "listPrice": 460000,
    "currency": "USD",
    "pricePerSqft": 285,
    "listDate": "2026-09-20T02:35:29.000Z",
    "propertyType": "single_family",
    "beds": 3,
    "baths": 2.5,
    "sqft": 1612,
    "lotSqft": 8015,
    "yearBuilt": 1982,
    "description": "Welcome to this stylishly updated home nestled on a private cul-de-sac lot...",
    "address": "7704 Fenton Cv",
    "city": "Austin",
    "stateCode": "TX",
    "postalCode": "78736",
    "countyName": "Travis",
    "latitude": 30.35,
    "longitude": -97.77,
    "agentName": "PATRICIA SMITH",
    "agentEmail": "patriciasmith@realtor.com",
    "agentPhone": "(512) 637-8277",
    "officeName": "Keller Williams Realty",
    "mlsName": "AUTX",
    "mlsNumber": "2816017",
    "photos": [
        "https://ap.rdcpix.com/.../1-m.jpg"
    ],
    "photoCount": 27,
    "daysOnMarket": 14,
    "searchUrl": "https://www.realtor.com/realestateandhomes-search/Austin_TX?page=1",
    "scrapedAt": "2026-09-20T12:00:00.000Z"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV or Excel.

#### All 165 fields

| Fields                                                                             | Example                                                                                      |
| ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `id`, `listingId`, `url`                                                            | `7363437439`, `2816017`, `https://www.realtor.com/realestateandhomes-detail/...`              |
| `status`, `mlsStatus`, `flags`, `tags`                                              | `for_sale`, `Active`, `isNewListing`, `central_air`                                           |
| `tagLabels` | the tags the site shows with the listing, in clear text (`Hardwood floors`, `View`); `tags` keeps the codes |
| `listPrice`, `currency`, `pricePerSqft`, `listPriceMin`, `listPriceMax`             | `460000`, `USD`, `285` — min / max for a new-construction price range                         |
| `priceReducedAmount`, `priceReducedDate`, `lastSoldPrice`, `lastSoldDate`           | `15000`, `2026-09-12T15:04:11.207Z`, `389900`, `2020-08-24`                                   |
| `listDate`, `lastUpdateDate`, `daysOnMarket`                                        | `2026-09-20T02:35:29.000Z` (what the date filters read), `14`                                 |
| `pendingDate`, `lastStatusChangeDate` | the day the listing went under contract and the last time its status changed (`2026-10-30T20:18:54.000Z`) — each when the site gives it |
| `availableDate` | rentals: the day the home can be moved into (`2026-11-15`) |
| `moveInDate`, `applicationUrl`, `acceptsOnlineApplications` | the day a new home can be moved into (`2027-04-30`), the link to apply online for a rental, and `true` when the rental takes online applications — each when the site gives it |
| `applicationFee`, `securityDeposit`, `petDeposit`, `petFee`, `petRent`, `leaseTermMonths` | **detail** — rentals: the application fee, the security deposit, the pet deposit, the one-time pet fee and the monthly pet rent in US dollars (`55`, `500`, `300`, `200`, `35`), and the lease lengths offered in months (`[6, 12]`) — each when the site lists it |
| `propertyType`, `propertySubType`, `yearBuilt`, `stories`, `garage`                 | `single_family`, `condo`, `1982`, `2`, `2`                                                    |
| `beds`, `baths`, `bathsFull`, `bathsHalf`, `sqft`, `lotSqft`, `hoaFee`              | `3`, `2.5`, `2`, `1`, `1612`, `8015`, `250`                                                   |
| `description`, `features`                                                           | the agent's own text; feature lines grouped by category (Appliances, Interior…)               |
| `address`, `city`, `state`, `stateCode`, `postalCode`                               | `7704 Fenton Cv`, `Austin`, `Texas`, `TX`, `78736`                                            |
| `streetNumber`, `streetName`, `streetSuffix`, `streetDirection`, `unit` | the address cut in parts (`7402`, `Rook`, `St`, `W`, `Unit 21`) — each when the site gives it; `address` stays the whole line |
| `countyName`, `countyFips`, `neighborhoods`, `latitude`, `longitude`, `streetViewUrl` | `Travis`, `48453`, `Oak Hill`, `30.35`, `-97.77`                                             |
| `agentName`, `agentEmail`, `agentPhone`, `agentPhones`, `agentPhotoUrl`, `agentWebsite` | `PATRICIA SMITH`, `patriciasmith@realtor.com`, `(512) 637-8277`, every number with its type, the agent's photo, the agent's website as a link. With **detail**, an empty e-mail or phone is filled with the one the MLS gives for the seller's agent, only when that agent has the same name (or the listing names no agent, then the name comes from the MLS too); otherwise the MLS contact stays in `mlsAgents` |
| `officeName`, `officeEmail`, `officePhone`, `officeWebsite`, `brokerName`, `mlsName`, `mlsNumber`, `listingSource` | `Keller Williams Realty`, `AUTX`, `2816017`, `mls` (or a builder, `new_home`, or a rental company, `community` / `unit_rental`) |
| `agentType`, `agentNrdsId` | `seller` (or `co_seller`, `community`, `management`), the agent's NRDS member number (`785030693`), when the site gives it |
| `agentLicense`, `agentProfileUrl` | **detail** — the agent's state license number (`0664627`) and their realtor.com page — each when the site gives it |
| `buyerAgentName`, `buyerOfficeName`, `coAgentName`, `mlsAgents` | for a sold home, the buyer's agent and their office; the second agent of the seller; and every agent the MLS lists, each with a name, a role (`seller`, `co_seller`, `buyer`, `co_buyer`) and an office. Some MLSs give the office only, so a name can be empty. With **detail**, the buyer's agent also comes with the office as the site writes it (`Jane Doe, Example Realty`), and each agent of `mlsAgents` also has an e-mail, a phone, the MLS's agent id, the office id and the office phone, when the MLS gives them |
| `buyerAgentEmail`, `buyerAgentPhone`, `buyerAgentLicense`, `buyerAgentWebsite`, `buyerOfficeEmail`, `buyerBrokerName` | **detail**, sold homes — the buyer's agent: e-mail, phone (the one the site marks primary), state license, website, the e-mail of their office and their broker — each when the site gives it |
| `daysOnMls`, `mlsBoard`, `providerUrl`, `createdAt`, `timezone` | **detail** — the days the MLS counts since the listing was entered, the board of realtors that runs the MLS (`Austin Board Of Realtors`), the listing on the website of the agency or the MLS, the day the site created the listing and the property's time zone (`America/Chicago`) — each when the site gives it |
| `virtualTours`, `matterportUrl`, `rentSpecials` | **detail** — every virtual tour (link, kind and category), the first Matterport link, and the specials of a rental (`Enjoy up to 8 Weeks Free`, with the start and end day when given); empty when there are none |
| `mlsFullName`, `listingKey`, `contractDate`, `indexedAt` | the full name of the MLS (`UnlockMLS`), the key the MLS gives the listing, the day the sale went under contract (`2026-11-11`) and the time the site indexed the listing — each when the site gives it |
| `builderName` | the home builder of a new-construction listing (`PERRY HOMES`) |
| `community` | the builder's program a new-construction listing belongs to, as one object with the same keys every time: name, page, text, builder and its site, state, number of homes, price / beds / baths / garage / size ranges, driving directions, amenities and the program's promotions; empty for any other listing |
| `promotions`, `promotionLabel` | the promotions of the listing itself (title, text, link), and the short label the site puts on the search card (`$8K closing`); empty when there is none |
| `mlsDisclaimer` | the notice the listing's MLS asks to show with it (`© 2026, Unlock MLS, All Rights Reserved.`), when the site gives it |
| `buildingName`, `subdivision`, `bathsThreeQuarter` | the name of the building or rental community (`461 Dean`), the subdivision (`Heritage Oaks Sec 2-B`, or the county's name for it) and the three-quarter baths (`1`) — each when the site gives it |
| `yearRenovated`, `buildingUnits`, `zoning` | **detail** — the year of the last renovation (`2017`), the number of units of the building (`122`) and the zoning code (`A-2`) — each when the site gives it |
| `brandingName`, `brandingType`, `brandingLogoUrl`, `brandingAccentColor` | the first brand the site shows on the listing: its name, its kind (`Agent`, `Office` or `Builder`), its logo and its accent color |
| `photos`, `photoCount`, `virtualTourUrl`, `openHouses`, `petPolicy`                 | 27 photo URLs, a Matterport link, the scheduled open houses, which pets a rental takes        |
| `hasMatterport` | `true` when the listing has a 3D tour, `false` when the site says it has none |
| `photoTags`, `photoDetails`, `primaryPhotoDetails` | the labels the site puts on the photos (`kitchen`, `bathroom`, `yard`), and for each photo, and for the main one, its link, its type and its labels with a probability (`0.999`) |
| `otherListings` | the other listings of the same home (earlier sales, rentals, relistings), each with its id, status, price, dates and whether it is the main one |
| `publicRecord` | the county's public record of the home (the tax roll) as one object with the same keys every time (a key is empty when the county has no value; the whole object is empty when the site has no record): record id and update day, subdivision, census tract, property type, beds, baths, sqft, lot size, stories, year built, garage. With **detail** it also has the parcel number, acres, building / gross / garage / first-floor / basement sqft, lot width and depth, rooms, units, year renovated, heating, cooling, electrical, water source, fireplace, construction, exterior, roofing, pool, zoning, view, styles and the legal description |
| `rentalUnits`, `unitCount` | rental communities: one entry per floor plan (name, beds, baths, sqft, rent, available day, first photo) and the number of plans. With **detail** each plan also has its top rent and deposit, and its units (number, floor, rent, beds, baths, sqft, available day, vacancy, amenities); a very large community is cut at 60 plans and 40 units per plan. Empty for any other listing. For a building, `unitCount` can also come from the detail |
| `priceHistory`, `taxHistory`, `estimates`, `estimatesHistory`, `estimatesForecast`  | **detail** — 39 listing events, 17 years of tax (each with the assessed and the market value), 3 value estimates with past and forecast     |
| `schools`, `floodScore`, `floodSeverity`, `femaZone`, `fireScore`, `noiseScore`, `noiseCategories`   | **detail** — nearby schools with their rating, the parents' rating and review count, the school's page and whether the home is assigned to it, students per teacher, each school's grades, address, position, GreatSchools id, NCES code and phone, and with `includeSchoolScores` the math and reading share at the state standard and its year; flood score and level (`minimal`), FEMA zone, fire / noise scores       |
| `schoolDistricts` | **detail** — the school districts the home is assigned to: id, name, NCES code, GreatSchools id, number of schools and students, the district office address and its county |
| `floorPlans` | **detail** with `includeFloorplans` — the floor plans of the listing, each with its kind (`2d`, `3d`, `interactive`, `cubicasa`), type, link and thumbnail; an empty list when it has none |
| `nearbyPlaces` | **detail** with `includeNearbyPlaces` — the shops and services around the listing, nearest first: name, categories, rating (null when nobody rated it), number of reviews, distance in miles, phone, address, position, website and link to its page; an empty list when not asked or when nothing is around |
| `neighborhoodStatsName`, `neighborhoodMedianDaysOnMarket`, `medianRentPrice` | **detail** — the first neighborhood of the listing with market figures (`Southeast Austin`), its median days on market and its median monthly rent in USD |
| `monthlyPayment`                                                                    | **detail** — mortgage estimate                                                                |
| `mortgageRate`, `mortgageLoanAmount` | **detail** — the interest rate in percent (`7.01`) and the loan amount in US dollars (`889000`) behind that estimate |
| `mortgageRateThirtyYearFixed`, `mortgageRateFifteenYearFixed`, `mortgageRateFiveYearArm` | **detail** — the site's average rate of the day, in percent, for a 30-year fixed, a 15-year fixed and a 5/1 adjustable loan (`7.01`, `6.146`, `6.45`) |
| `rentEstimate`, `rentEstimateLow`, `rentEstimateHigh`                               | **detail** — the monthly rent the site estimates for the home, with its range (`2502`, `2279.25`, `2724.75`) |
| `stats`                                                                             | **option** `includeViewStats` — views, clicks, saves, shares and enquiries per period          |
| `buildingPermits`, `hasRoofPermit`                                                  | **option** `includePermitHistory` — each permit (project, type of work, date, status); `true` when one is a roof job |
| `searchRank`, `searchPage`, `totalResults` | the place of the listing in its search (`1` = first result of that search), the results page it was on, and the number of listings the site announced for the search — empty for a listing URL given in `startUrls` |
| `searchUrl`, `scrapedAt`                                                            | the search it was found through, ISO timestamp                                                |

### 💡 Tips

#### How to get more results

One search returns at most 10,000 listings — that is the site's own limit, not the Actor's. Above it, the Actor splits the search into price bands, and each band again until every piece fits — sold homes into sale-date ranges instead, since many of them have no price — so a whole state comes out in one run. The few listings with no price at all (about 1 in 1,000 rentals, fewer for sale) cannot be reached by a price band; sold homes lose none. The count the site shows also counts twice a home listed by two sources (two MLS, or an MLS and a rental manager): it comes out once, under one id and one URL. Measured on whole searches: Harris County for sale, 29,279 listings for a count of 29,403; Arizona rentals, 35,456 for 35,842. You can also split a search yourself by putting several ZIP codes in `locations`. Set `maxItems` to `0` to take everything a search has.

#### How to reduce costs

The price is per listing, so the levers are `maxItems`, `maxItemsPerQuery`, the filters (a filtered-out listing costs only its filter check, $0.04 per 1,000, $0.01 on the Gold plan) and `onlyNew` for recurring runs (you never pay twice for the same listing). Leaving `extractDetails` off keeps listings at the lower price: the search results already carry description, photos and the agent's contact details.

#### Count the listings of a search first

Tick **Count only** (`countOnly`) to see how many listings each of your searches has before you read them. The run answers in seconds, saves nothing to the dataset, and charges only its start. Open the `SEARCH_COUNTS` record of the run's key-value store: one entry per search with its place, keyword, status, link and `total`, and `totalListings` for the whole run (a listing found by two searches counts twice there). A search the site could not count has `total: null` and a `note` (never 0). A search with a total above 10,000 is counted whole, even though a normal run reads it in pieces. A listing URL in `startUrls` has no count. The filters you set (place, status, price, beds, map area…) are part of the search and are counted; the post-filters (`postedAfter`, `postedBefore`, `excludeKeywords`, `requirePhone`) are not.

#### Several searches in one run

Fill `locations` and / or `searchQueries`: the Actor runs one search per location × keyword (3 keywords × 4 cities = 12 searches, up to 500 per run). The single `location` and `query` fields still work and are added to the lists. A listing found by several searches is saved — and charged — once. Set `maxItemsPerQuery` to give every search its own cap: without it the first searches can use up the whole `maxItems` budget. You can also paste several search URLs into `startUrls`: each one is a search of its own, with the same cap.

#### Monitoring: only the new listings

Tick **Only new listings** (`onlyNew`) and schedule the Actor. The first run returns everything; each later run skips the listings already delivered: they are not saved, not charged, and no detail request is made for them. The memory lives in a named key-value store of your account (`realtor-listings-scraper-seen`, up to 150,000 listings per key) and is only updated with listings that really reached the dataset, so a failed run never hides anything. Give each schedule its own `stateKey` (two schedules sharing a key would hide each other's listings), and tick `resetState` once to start over. The searches of the form are then sorted by listing date, newest first (rentals: in the order they were published, which also reaches the rentals that carry no date; a pasted URL keeps its own sort), and a search stops once it meets 200 listings in a row that you already have — or, under a lower `maxItems` / `maxItemsPerQuery`, 80 % of that cap in all (a listing of the block the last run delivered may have been sold or relisted since). Realtor.com dates a listing by the day it first went on the market and never moves that date afterwards, so a listing you already have cannot climb back above a new one. Rental buildings (apartment communities) are the exception: the site puts them back on top each time they are updated, so they never count in those 200, and one you already have is still skipped.

#### Filter by listing date

`postedAfter` and `postedBefore` take a date (`2026-09-01`, the whole day is included, site time zone) or a period before now (`7 days`, `2 weeks`, `1 month`; via the API also `24 hours` or a full ISO date-time). The filter reads `listDate`, the moment the listing went on the market; a listing without one is dropped as soon as a date bound is set. Filtered-out listings are not saved and do not count in `maxItems` (each listing checked costs the filter fee, see pricing); the run summary tells how many were filtered. With `postedAfter`, the searches of the form are sorted by newest and stop at the first page that is entirely too old; a URL pasted into `startUrls` keeps its own sort, and stops early only when it is sorted by newest listing date — otherwise it is read to its end, each listing checked.

### 🔌 Integrations and API

Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.

### 🤖 Use with AI agents (MCP)

AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the [Apify MCP server](https://mcp.apify.com), billed to their Apify account like any run. It returns one item per Realtor.com property listing. Actor id: `nice_dev/realtor-listings-scraper`; MCP server with this Actor only: `https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/realtor-listings-scraper`.

Smallest input, for a cheap first call:

```json
{
    "location": "Austin, TX",
    "maxItems": 10
}
```

Key output fields: `url`, `status`, `listPrice`, `beds`, `baths`, `sqft`, `address`, `agentPhone`.

Cost: $0.45 per 1,000 listings plus $0.01 per run start ($0.42 per 1,000 on the Gold plan); **Extract details**, the permit and view-statistics options and the Actor's own filters cost extra, see the pricing section above. Cap each call with `maxItems` and, through the API, with the run option `maxTotalChargeUsd`.

### ❓ FAQ

#### Is it legal to scrape Realtor.com?

The Actor only reads what Realtor.com shows publicly to any anonymous visitor. It logs in to nothing. Results contain the contact details of **licensed real-estate professionals** acting in their trade, and personal data is protected by GDPR and by US state privacy laws: do not store it without a legitimate reason, and do not use it for unsolicited marketing where that is restricted. Listing content comes from local MLS boards and its redistribution can be limited by their rules. You are responsible for using the data in compliance with Realtor.com's Terms of Use and applicable law. This Actor is not affiliated with Realtor.com, Move, Inc. or the National Association of REALTORS®.

#### Does it need a login or a proxy?

No login. The proxy is included in the price: leave the default setting (the residential proxy is not available). A request the site turns away is retried at once on a new proxy session (without a proxy, after a pause of 5 seconds, doubled at each retry up to 150 seconds).

#### Which fields can be empty?

Realtor.com does not publish everything for every listing, and the Actor never invents a value: a field it has no data for is `null` or an empty list. Measured on 800 real listings of every kind: `agentEmail` and `agentPhone` are there on about 6 listings in 10 (almost always on sold listings, less often on new ones), `beds` / `baths` / `sqft` are missing on land and mobile homes, and `lastSoldPrice` is `null` in non-disclosure states such as Texas and Utah, where sale prices are not public records. With `extractDetails` on and measured on 30 listings: price history and schools on all of them, tax history on 20, value estimates on 22. With the options on (26/09, 450 listings): building permits on 169 of 300 listings in Austin (5 rows on average, up to 20) and 116 of 150 in Tampa, where 69 carry a roof permit; view counts on 426 of 450 — a brand-new listing has none yet, the site starts counting a few days after it goes up.

#### Is the data safe to open in Excel or to show on a web page?

Descriptions are the agents' own words, copied as they are, and a text can begin with `-`, `+`, `=` or `@` (a phone number, a line such as `-20% price cut`): Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. Every URL field (`url`, `photos`, `virtualTourUrl`, `streetViewUrl`, `agentPhotoUrl`) holds an http(s) URL or `null` — nothing else gets through. On a web page, escape every field like any text written by a stranger.

#### Known limitations

- Site filters that are not in the input can still be used by pasting a filtered search URL into `startUrls`. A URL whose filters the Actor cannot apply is refused by name instead of being run without them.
- One search returns at most 10,000 listings on the site itself; bigger searches are split automatically, and `maxItemsPerQuery` still counts for the whole search, not for each piece. Past 10,000, the listings come band by band: the sort order holds within each band, not across the whole search.
- `daysOnMarket` is counted from `listDate`: Realtor.com leaves its own field empty. For a sold home it stops at the sale day (`lastSoldDate`).
- `onlyNew` remembers listing ids, not their content: a listing whose price changed is not returned again.
- Rentals: part of the rental listings carry no listing date on Realtor.com (12 % in Austin, 61 % across Arizona), so their `listDate` and `daysOnMarket` are empty. `onlyNew` still returns the new ones (rentals are read in the order they were published); `postedAfter` / `postedBefore` leave them out.
- Sold homes: many sales were never listed and come from public records (30 % of Texas sales, a third to a half in some cities). They have no `listPrice`, `listDate`, MLS number, agent or description (`listingSource` is empty); sorted by listing date, sale date or price they come last, sorted by size or last update they are mixed in.
- "Sold in the last N days" counts from the day the run started (New York time), for its whole length — a resurrected run keeps that day.
- Off market: an expired listing may carry no listing date (its `listDate` and `daysOnMarket` are then empty, and `postedAfter` / `postedBefore` leave it out); `flags.isForRent` tells an expired rental from an expired sale. Past 10,000 listings the search is cut by price, which leaves out the few listings that have no price.
- Ready to build: a builder plan has no `listingId` (the `id` is the property id) and `flags.isPlan` is true; some plans have no price. `mlsOnly` and `builderSpecHomesOnly` cannot be used with it.
- Off market and ready to build with `onlyNew`: the run reads the whole search every time and skips what it already delivered (these listings are not ordered by the moment they appear), so it takes as long as a full run without `onlyNew`.
- Two runs sharing the same `stateKey` at the same time may both return the same new listing.

**A run that reaches its timeout** stops itself about 45 seconds before it: no new page is asked, what it read is saved and, with `onlyNew`, remembered, and the run ends *Succeeded* with "Stopped before the run's timeout". Resurrect it to go on from there, or give the next run a longer timeout (Run options).

**A run the platform stops without warning** (out of memory)

- Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the listings already saved are skipped: none is delivered or charged twice, and `maxItems` still counts them.
- With `onlyNew`, the memory is saved after each write (at most once every 2 seconds): resurrect the stopped run and the listings it had saved meanwhile join the memory; leave it stopped for good, and the next run may return the listings of its last 2 seconds once more.

#### Something doesn't work?

The last line of the log counts the listings saved, filtered out and no longer on Realtor.com (removed while the run was reading them), and the requests that failed after every retry. Those requests and the removed listings are listed, with the reason, in the `FAILED_REQUESTS` record of the run's key-value store. A run that saved nothing and had failed requests fails, and its last message gives the cause (a location the site does not know says so, instead of "run it again"). A run that saved some listings fails too when at least as many requests failed for good as were read: a green run with a short dataset would hide an outage. One failed request among many is only a warning.

If Realtor.com changes its pages, you are told instead of paying for blank rows. A results page that counts listings but gives none the Actor can read is an error (listed in `FAILED_REQUESTS`), never a quiet "No listings found". If the first 20 listings read all lack their URL, status, price or listing date (rentals aside), last update date, property type, address, city, state, ZIP code, county, MLS number or — with details — price history, the run saves nothing more, stops and fails, and its last message names the missing field: at most those first listings are charged. A listing that `postedAfter` / `postedBefore` drops because it has no date at all counts among those 20. With details, if the first 20 listings of the run all come back as no longer on Realtor.com, the run stops and fails the same way, with nothing charged.

### 🛟 Support

Open an issue in the **Issues** tab with a link to your run: the run log and the `FAILED_REQUESTS` record of the key-value store show exactly which URLs failed and why.

# Actor input Schema

## `startUrls` (type: `array`):

Realtor.com search URLs (`https://www.realtor.com/realestateandhomes-search/Austin_TX/beds-3/price-300000-600000`), sold pages (`/soldhomeprices/...`) or rental pages (`/apartments/...`). Filters written in the URL and read as the site reads them: price, beds, baths, sqft, lot size (lot-sqft), home age (age-N, age-N+), days on market (dom-N, show-newest-listings), HOA (hoa-no, hoa-N: no HOA or up to N), garage, property type, radius, pnd-hide, fc-hide, nc-hide, 55p-hide, show-open-house, show-foreclosure, shw-nc, show-virtual-tours, show-recently-sold (soldwithin-1/3/6/12), pet-friendly rentals and the sorts sby-1 (price up), sby-2 (price down), sby-6 (newest), sby-14 (sqft), sby-16 (photos). Other sorts are ignored with a warning in the log (a sort changes the order, not which listings come out); /overview is ignored. A filter the Actor cannot apply (features and keywords, price reduced, 55+ only, existing homes only) is refused by name with the field to use instead, never dropped in silence. When this list is not empty, the search fields below are ignored; caps, date filters and monitoring still apply. Max 1 000 URLs.

## `location` (type: `string`):

City, ZIP code, county or state, as typed on Realtor.com (e.g. `Austin, TX`, `78704`, `Texas`). Empty = only the locations listed below are used.

## `locations` (type: `array`):

Several locations in one run: one search per location (times each keyword below). Added to **Location** (3 keywords × 4 locations = 12 searches, max 500). Listings found by several searches are saved once.

## `query` (type: `string`):

Free-text keyword matched against the listing text, as on Realtor.com (e.g. `pool`, `waterfront`, `new roof`). Empty = no keyword filter.

## `searchQueries` (type: `array`):

Several keywords in one run: every keyword is searched in every location (3 keywords × 4 locations = 12 searches, max 500). Added to **Search keyword**.

## `listingStatus` (type: `string`):

Which listings to search: for sale, for rent, recently sold, pending, coming soon, off market (listings that expired without a sale or a rental) or ready to build (builder plans for homes not yet built).

## `propertyType` (type: `array`):

Keep only these property types. Empty = all types. Values measured on Austin, TX (7 041 listings): single-family 4 424, condos 1 602, townhomes 137, multi-family 223, land 552, mobile 78, farm 25.

## `maxItems` (type: `integer`):

Maximum number of listings to save for the whole run (after deduplication and filters). 0 = no limit.

## `maxItemsPerQuery` (type: `integer`):

Cap for each single search (one location × one keyword), so one big city cannot eat the whole run. 0 = no per-search cap.

## `countOnly` (type: `boolean`):

Only count how many listings each search has, without reading them. You get one number per search (and one for the whole run) in the **SEARCH_COUNTS** record of the run's key-value store and in the log; the dataset stays empty and nothing is charged but the start of the run. Max listings, Extract details, the options, post-filters and Only new listings are not used. A search the site cannot count shows `null` (never 0). A listing URL has no count.

## `extractDetails` (type: `boolean`):

Open each listing's detail page to add price history, tax history, nearby schools, flood / fire / noise risk and value estimates. Read 25 listings per extra request (a little slower, charged as a separate event). Off = the search results only, which already carry description, photos and agent contact.

## `includePermitHistory` (type: `boolean`):

Add the building permits filed on each property (type of work, project, date, status) and a <code>hasRoofPermit</code> flag to spot roofing jobs at a glance. Charged per permit row delivered (3 permits = 3 events, a property with none = 0). Reads the listing's detail page, so Extract details is turned on with it.

## `includeFloorplans` (type: `boolean`):

Add the floor plans the listing carries (<code>floorPlans</code>: kind, type, link, thumbnail). Needs Extract details turned on: the plans are read from the listing's detail, in the same request, at no extra charge.

## `includeSchoolScores` (type: `boolean`):

Add, for each nearby school, the share of tested students at the state standard in math and reading (<code>mathProficiency</code>, <code>readingProficiency</code>, <code>testYear</code>). Needs Extract details turned on. The site's answer is heavier (about 13 KB more per listing), so the run is a little slower. The students-per-teacher ratio is always in the schools, with or without this.

## `includeNearbyPlaces` (type: `boolean`):

Add the shops and services around each listing (<code>nearbyPlaces</code>: name, categories, rating, number of reviews, distance in miles, phone, address, position, website, link), nearest first, in the categories chosen below. Needs Extract details turned on: they are read from the listing's detail, in the same request, at no extra charge. The site's answer is a little heavier, so the run is slightly slower.

## `nearbyPlaceCategories` (type: `array`):

Which kinds of places to list when <b>Include places nearby</b> is on. Each category gives its nearest places (up to the number set below). Empty = restaurants, grocery stores and coffee and tea.

## `nearbyPlacesRadiusMiles` (type: `integer`):

How far from the listing to look for places, in miles (1 to 25). Used only with <b>Include places nearby</b>.

## `nearbyPlacesPerCategory` (type: `integer`):

How many places to keep in each category, the nearest first (1 to 10). Used only with <b>Include places nearby</b>.

## `includeViewStats` (type: `boolean`):

Add how many times each listing was viewed, clicked, saved, shared and enquired about over the last 1, 7, 30 days… as counted by Realtor.com. Charged per listing whose statistics are delivered (brand-new listings have none yet and cost nothing). Reads the listing's detail page, so Extract details is turned on with it.

## `sortBy` (type: `string`):

Order the site returns the listings in. Newest first is the one to use for monitoring. The sold price sorts are for **Sold** listings only and the availability sort for **For rent** listings only: with any other status the input is refused before the run starts. Builder plans have no listing number: they are ordered by your sort, then by a fixed list of other keys, so every plan is read once.

## `minPrice` (type: `integer`):

Listing price, in US dollars. For rentals this is the monthly rent.

## `maxPrice` (type: `integer`):

Listing price, in US dollars.

## `minBedrooms` (type: `integer`):

Minimum number of bedrooms.

## `maxBedrooms` (type: `integer`):

Maximum number of bedrooms.

## `minBathrooms` (type: `number`):

Half bathrooms count as 0.5 (e.g. `2.5`).

## `maxBathrooms` (type: `number`):

Maximum number of bathrooms, half bathrooms counted as 0.5.

## `minSqft` (type: `integer`):

Interior living area, in square feet.

## `maxSqft` (type: `integer`):

Maximum interior living area, in square feet.

## `minLotSqft` (type: `integer`):

Lot size, in square feet (1 acre = 43 560 sqft).

## `maxLotSqft` (type: `integer`):

Maximum lot size, in square feet.

## `maxHoaFee` (type: `integer`):

Maximum monthly homeowners association fee, in US dollars. Listings without a fee are kept.

## `minYearBuilt` (type: `integer`):

Keep only properties built in this year or later.

## `maxYearBuilt` (type: `integer`):

Keep only properties built in this year or earlier.

## `minGarage` (type: `integer`):

Minimum number of garage spaces.

## `radiusMiles` (type: `integer`):

Widen the search around the location, in miles (Realtor.com's own radius). 0 = the location's own boundary.

## `soldWithinDays` (type: `integer`):

Only listings sold in the last N days, counted in US calendar days (New York time) from the day the run started, that day included. Applies to **Sold** listings only. 0 = no limit.

## `foreclosureOnly` (type: `boolean`):

Only properties in foreclosure.

## `newConstructionOnly` (type: `boolean`):

Only newly built properties.

## `openHousesOnly` (type: `boolean`):

Only listings with an open house scheduled.

## `virtualTourOnly` (type: `boolean`):

Only listings that come with a virtual tour or a 3D walkthrough.

## `noHoaFeeOnly` (type: `boolean`):

Only listings without homeowners association fees.

## `excludePending` (type: `boolean`):

Homes for sale only (not off market or ready to build): leave out the listings already under contract. Realtor.com keeps them in its for-sale results: from 1 in 7 (Houston) to 1 in 3 (Chicago).

## `mlsOnly` (type: `boolean`):

Only listings published through an MLS by a licensed agent. Leaves out builders' new-home plans (so it cannot be used with **Ready to build**, which is made of them) and the apartments that rental companies post themselves (from 3 rentals in 10 in Houston to 9 in 10 in Seattle).

## `petsAllowed` (type: `array`):

Rentals that accept these pets. Only for **For rent** listings: with any other status the input is refused before the run starts, since Realtor.com rejects it.

## `priceReducedWithinDays` (type: `integer`):

Only listings whose price dropped in the last N days, counted in US calendar days (New York time) from the day the run started. 0 = no limit.

## `priceReduced` (type: `boolean`):

Only listings whose price has dropped at least once. If "Price dropped within days" is also set, that one is used.

## `openHouseWithinDays` (type: `integer`):

Only listings with an open house today or in the next days: 1 = today only, 7 = the next 7 days, today included. Times are those of the house. Not together with "Open house from" / "Open house to". 0 = off.

## `openHouseFrom` (type: `string`):

Only listings with an open house on or after this day (YYYY-MM-DD).

## `openHouseTo` (type: `string`):

Only listings with an open house on or before this day (YYYY-MM-DD), that whole day included.

## `has3DTour` (type: `boolean`):

Only listings that come with a 3D tour or a virtual tour. "Virtual tour only" above keeps the virtual tours alone.

## `withPhotoOnly` (type: `boolean`):

Only listings that have at least one photo.

## `features` (type: `array`):

Only listings that carry all the features you pick (the tags Realtor.com puts on a listing). For any other tag of the site, use "Tags" below.

## `tags` (type: `array`):

Realtor.com listing tags, one per line, in lower case with "\_" between words (for example `cul_de_sac`, `hardwood_floors`). The listing must carry all of them, those of "Features" included. A tag the site does not know gives no result.

## `seniorCommunity` (type: `string`):

Any = the site's own mix. Only = the 55+ communities alone. Hide = leave them out.

## `mlsListingId` (type: `string`):

Only the listing that has this number in its MLS (for example `2427357`). Use it with the place of the listing: the same number can exist in two MLS.

## `moveInBy` (type: `string`):

Rentals available on or before this day (YYYY-MM-DD). Applies to **For rent** listings only.

## `builderPromotions` (type: `boolean`):

Only homes for sale and builder plans (**Ready to build**) whose builder or community runs a promotion. Not for rent, sold or off market listings.

## `rentSpecials` (type: `boolean`):

Only rentals that advertise a special offer. Applies to **For rent** listings only.

## `applyNow` (type: `boolean`):

Only rentals you can apply for online on Realtor.com (they carry an application link). Applies to **For rent** listings only.

## `soldAfter` (type: `string`):

Only listings sold on or after this day (YYYY-MM-DD). Applies to **Sold** listings only; with "Sold within days" the later start is used.

## `soldBefore` (type: `string`):

Only listings sold on or before this day (YYYY-MM-DD), that whole day included. Applies to **Sold** listings only.

## `boundingBox` (type: `object`):

Only listings inside a rectangle of the map: <code>{"minLatitude": 30.25, "maxLatitude": 30.29, "minLongitude": -97.76, "maxLongitude": -97.72}</code>. Works with or without a location (with one, it narrows it). Empty = no map box.

## `polygon` (type: `array`):

Only listings inside a polygon: a list of corners written <code>\[longitude, latitude]</code> (the longitude first), 3 to 200 corners in order around the area (the first corner may be repeated at the end). A polygon that crosses itself is refused. Works with or without a location. Empty = no polygon.

## `centerPoint` (type: `object`):

Only listings within a radius of a point: <code>{"latitude": 30.27, "longitude": -97.74, "radiusMiles": 2}</code> (radius 1 mile if left out, 50 at most). Works with or without a location. Empty = no circle.

## `mapAreas` (type: `array`):

Up to 20 areas in one run, each one a box (<code>minLatitude</code>, <code>maxLatitude</code>, <code>minLongitude</code>, <code>maxLongitude</code>), a circle (<code>latitude</code>, <code>longitude</code>, <code>radiusMiles</code>) or <code>{"polygon": \[\[longitude, latitude], ...]}</code>. Each area is searched on its own (with each location, if you give several). Empty = none.

## `street` (type: `string`):

Only listings on this street (<code>Congress Ave</code>) or at this address (<code>805 Congress Ave</code>). Works with or without a location (with one, the street is searched in it).

## `agentName` (type: `string`):

Only listings whose selling agent has this name, typed as the site writes it. Applied by the site.

## `officeName` (type: `string`):

Only listings from this real estate office, typed as the site writes it (for example `Keller Williams Realty`). Needs a place (a location, a map area or a street): without one the input is refused before the run starts, since the site fails. Applied by the site.

## `minElementarySchoolRating` (type: `integer`):

Only homes served by an elementary school rated at least this, from 1 to 10. 0 or empty = no limit. Applied by the site.

## `minMiddleSchoolRating` (type: `integer`):

Only homes served by a middle school rated at least this, from 1 to 10. 0 or empty = no limit. Applied by the site.

## `minHighSchoolRating` (type: `integer`):

Only homes served by a high school rated at least this, from 1 to 10. 0 or empty = no limit. Applied by the site.

## `schoolDistrict` (type: `string`):

Only homes in this school district, written exactly as the site names it (for example `Austin Independent School District`). Applied by the site.

## `minSoldPrice` (type: `integer`):

Only listings that sold for at least this price, in US dollars. Applies to **Sold** listings only. States that do not publish sale prices return nothing with this filter. Applied by the site.

## `maxSoldPrice` (type: `integer`):

Only listings that sold for at most this price, in US dollars. Applies to **Sold** listings only. States that do not publish sale prices return nothing with this filter. Applied by the site.

## `commuteFrom` (type: `string`):

Only homes within a trip of this point, written latitude,longitude (for example `30.2672,-97.7431`). Set the time in "Commute time" and the way in "Commute by": both are ignored without a point. Applied by the site.

## `commuteMinutes` (type: `string`):

Longest trip from the commute point, in minutes. Ignored without a point.

## `commuteMode` (type: `string`):

How the trip is made. Ignored without a commute point.

## `floodRisk` (type: `string`):

Only homes whose flood risk is exactly this level (not "at most"). Any = no filter. Applied by the site.

## `fireRisk` (type: `string`):

Only homes whose fire risk is exactly this level (not "at most"). Any = no filter. Applied by the site.

## `windRisk` (type: `string`):

Only homes whose wind risk is exactly this level (not "at most"). Any = no filter. Applied by the site.

## `heatRisk` (type: `string`):

Only homes whose heat risk is exactly this level (not "at most"). Any = no filter. Applied by the site.

## `airRisk` (type: `string`):

Only homes whose air quality risk is exactly this level (not "at most"). Any = no filter. Applied by the site.

## `auctionOnly` (type: `boolean`):

Only homes listed for auction. Applied by the site.

## `shortSaleOnly` (type: `boolean`):

Only homes listed as short sales. Applied by the site.

## `fractionalOwnershipOnly` (type: `boolean`):

Only homes sold in shares (fractional ownership). Applied by the site.

## `excludePropertyTypes` (type: `array`):

Leave out these property types (for example land). Empty = leave none out. Not together with "Property type": the site fails when both are sent, so the input is refused. Applied by the site.

## `matterportOnly` (type: `boolean`):

Only listings with a 3D scan of the inside made with Matterport. Applied by the site.

## `builderSpecHomesOnly` (type: `boolean`):

Only spec homes, built by a builder before a buyer was found. Only for homes for sale: with a rental, sold, off market or ready to build status the input is refused before the run starts. Applied by the site.

## `noPetsAllowed` (type: `boolean`):

Only rentals that do not take pets. Only for **For rent** listings: with any other status the input is refused before the run starts. Not together with "Pets allowed". Applied by the site.

## `excludePropertyIds` (type: `array`):

Property ids to leave out of the results, the id of a row (for example `9954799904`), one per line, up to 500. Handy to skip homes you already have. Applied by the site.

## `postedAfter` (type: `string`):

Keep listings put on the market on or after this date — the listing's `listDate`. Absolute (`2026-09-01`, or a full ISO timestamp) or relative (`7 days`, `24 hours`, `2 weeks`). Listings filtered out are not saved, and a search of the form, read newest first, stops at the first page that is entirely older (a pasted URL keeps its own sort).

## `postedBefore` (type: `string`):

Keep listings put on the market on or before this date — the listing's `listDate`. Same formats as above.

## `excludeKeywords` (type: `array`):

Drop a listing when one of these WHOLE words appears in its address, city or description (case and accents ignored): `pool` drops "Pool and spa" but keeps "Liverpool Rd". Several words in one entry (`hand made`) must appear together, in that order, inside the same field. Chinese, Japanese, Korean, Thai, Lao, Khmer and Burmese words are found anywhere in the text (no spaces there). Applied after the site's own filters.

## `requirePhone` (type: `boolean`):

Drop listings whose agent has no phone number.

## `onlyNew` (type: `boolean`):

Return only the listings that were not delivered by a previous run with the same **State key**. The first run returns everything and remembers it. With **Off market** and **Ready to build** the run reads the whole search each time (their order does not follow the news) and skips the listings it already delivered; it remembers up to 150,000 delivered listings per State key.

## `stateKey` (type: `string`):

Name of the memory used by **Only new listings**. Use a different key for each saved search so they do not share their history.

## `resetState` (type: `boolean`):

Forget everything remembered under this **State key** before starting, so the next run returns every listing again.

## `proxyConfiguration` (type: `object`):

Leave the default: the proxy is included in the price. Residential proxies are not available for this Actor.

## `maxConcurrency` (type: `integer`):

Maximum number of requests running at the same time.

## `maxRequestsPerMinute` (type: `integer`):

Upper bound on the request rate, to stay polite with the site.

## `maxRequestRetries` (type: `integer`):

How many times a failed request is retried before it is given up.

## `debugLog` (type: `boolean`):

Log every request and every filter decision. Useful to report a problem.

## Actor input object example

```json
{
  "startUrls": [],
  "location": "Austin, TX",
  "locations": [],
  "searchQueries": [],
  "listingStatus": "for_sale",
  "propertyType": [],
  "maxItems": 100,
  "maxItemsPerQuery": 0,
  "countOnly": false,
  "extractDetails": false,
  "includePermitHistory": false,
  "includeFloorplans": false,
  "includeSchoolScores": false,
  "includeNearbyPlaces": false,
  "nearbyPlaceCategories": [
    "restaurants",
    "grocery",
    "coffee"
  ],
  "nearbyPlacesRadiusMiles": 2,
  "nearbyPlacesPerCategory": 5,
  "includeViewStats": false,
  "sortBy": "list_date:desc",
  "radiusMiles": 0,
  "soldWithinDays": 0,
  "foreclosureOnly": false,
  "newConstructionOnly": false,
  "openHousesOnly": false,
  "virtualTourOnly": false,
  "noHoaFeeOnly": false,
  "excludePending": false,
  "mlsOnly": false,
  "petsAllowed": [],
  "priceReducedWithinDays": 0,
  "priceReduced": false,
  "openHouseWithinDays": 0,
  "has3DTour": false,
  "withPhotoOnly": false,
  "features": [],
  "tags": [],
  "seniorCommunity": "any",
  "builderPromotions": false,
  "rentSpecials": false,
  "applyNow": false,
  "commuteMinutes": "20",
  "commuteMode": "drive",
  "floodRisk": "any",
  "fireRisk": "any",
  "windRisk": "any",
  "heatRisk": "any",
  "airRisk": "any",
  "auctionOnly": false,
  "shortSaleOnly": false,
  "fractionalOwnershipOnly": false,
  "excludePropertyTypes": [],
  "matterportOnly": false,
  "builderSpecHomesOnly": false,
  "noPetsAllowed": false,
  "excludePropertyIds": [],
  "excludeKeywords": [],
  "requirePhone": false,
  "onlyNew": false,
  "stateKey": "default",
  "resetState": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 8,
  "maxRequestsPerMinute": 120,
  "maxRequestRetries": 5,
  "debugLog": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `searchCounts` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "location": "Austin, TX",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nice_dev/realtor-listings-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "location": "Austin, TX",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("nice_dev/realtor-listings-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "location": "Austin, TX",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call nice_dev/realtor-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/realtor-listings-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/MA4adNWRBZ6SjpenG/builds/MmvEv21gFGNR9C8M1/openapi.json
