Realtor.com Listings Scraper
Pricing
from $0.75 / 1,000 results
Realtor.com Listings Scraper
Scrape Realtor.com by city, state or ZIP and get up to 200 listings per location in one request: numeric price, beds, consolidated baths such as 2.5, areaSqft, lotSizeSqft, status, agentName, brokerName, detailUrl and coordinates. For sale, for rent or recently sold. No account needed.
Pricing
from $0.75 / 1,000 results
Rating
0.0
(0)
Developer
String
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
15 days ago
Last modified
Categories
Share
What does the Realtor.com Listings Scraper do?
Point this Actor at US locations — a city with its state, or a bare ZIP code — and it returns up to 200 Realtor.com listings for each one in a single request. Rows carry a numeric price, beds, baths, living area, lot size and coordinates, plus the listing agent and the brokerage behind them.
Realtor.com renders its search results in the browser, so there is nothing useful in the served HTML: 34 card skeletons, eight hydrated cards, and a schema.org block that omits baths, lot size, status, agent, broker and coordinates entirely. This Actor calls the same search API the page itself calls, which returns all of those as values in one round trip.
- 200 listings per location, against roughly 40 on the visible first page
agentNameandbrokerNameon every row, which no other surface of the page publishes togetherbathsis Realtor.com's consolidated count, so a home with two full baths and a powder room reads as2.5rather than2- On a
soldrow,priceis the price it sold for wherever Realtor.com discloses it - No account, cookie or API key anywhere in the run
What data does it extract?
| Field | Type | Description |
|---|---|---|
propertyId | string | Realtor.com's own property ID, stable across runs. Use it to de-duplicate |
address | string | Street line |
city | string | City |
state | string | Two-letter state code |
zipcode | string | Postal code |
price | number | Sold price on a sold row, otherwise the list price |
beds | number | Bedroom count |
baths | number | Consolidated bathroom count, e.g. 2.5 |
areaSqft | number | Living area in square feet |
lotSizeSqft | number | Lot size in square feet |
status | string | for_sale, ready_to_build, for_rent or sold |
agentName | string | Listing agent, where Realtor.com names one |
brokerName | string | Brokerage or office as the listing displays it |
latitude | number | Decimal degrees |
longitude | number | Decimal degrees |
detailUrl | string | Link to the Realtor.com listing page |
searchLocation | string | The location from your input that produced this row |
sourceUrl | string | The human Realtor.com search page for that location |
collectedAt | string | ISO timestamp of the fetch |
brokerName is the office name as the listing shows it rather than the broker of record, because
the broker-of-record string reads like an internal record ("Compass RE Texas, LLC. - Broker") and is
not what anyone wants in a spreadsheet.
Why scrape Realtor.com?
- Comps that include the lot. Sold rows carry
price,areaSqftandlotSizeSqfttogether, which is the minimum set for a defensible price-per-square-foot comparison. - Agent and brokerage lead lists. Every location returns agent and office names attached to live inventory, so you can rank agents by what they actually have listed.
- New construction tracking. Realtor.com files unbuilt but marketed homes under
ready_to_build, and the defaultfor_salesearch includes them, so you can separate spec homes from resale. - Rental inventory.
listingType: "for_rent"reads the apartments surface, giving asking rents next to bed counts for the same market. - A second opinion on Zillow. MLS coverage differs between portals; running both and joining on address catches listings one of them is missing.
How to use it
- Open the Actor and click Try for free, or add it to your Apify account.
- Enter locations in the Locations field, one per line.
Austin, TXand78704are both valid; a city without its state is ambiguous and may resolve somewhere you did not intend. - Choose a Listing type from the dropdown:
for_sale,for_rentorsold. - Optionally lower Maximum results. A value below 200 also narrows each request, so it saves time as well as spend.
- Click Start. One location is one request, so even twenty markets finish quickly.
- Export from the Dataset tab as JSON, CSV or Excel, and read the run's
SUMMARYrecord for any location that failed.
Input
| Field | Type | Default | Description |
|---|---|---|---|
locations | array of strings | required | Cities with state ("Austin, TX") or ZIP codes. Between 1 and 100 entries. Duplicates collapse to one request |
listingType | string | for_sale | One of for_sale, for_rent, sold. for_sale also returns ready_to_build new construction |
maxItems | integer | 1000 | Ceiling on dataset rows, 1 to 50000. Below 200 it also narrows the per-location request |
concurrency | integer | 2 | Locations fetched in parallel, 1 to 5 |
{"locations": ["Austin, TX", "78704", "Boise, ID"],"listingType": "for_sale","maxItems": 1000,"concurrency": 2}
Output
One row per listing. The shape below is illustrative — it shows the fields and their types, not a captured run.
{"propertyId": "9124738201","address": "6310 Needham Ln","city": "Austin","state": "TX","zipcode": "78739","price": 1200000,"beds": 5,"baths": 4.5,"areaSqft": 3496,"lotSizeSqft": 9121,"status": "for_sale","agentName": "Dana Whitfield","brokerName": "Compass RE Texas, LLC","latitude": 30.192585,"longitude": -97.89119,"detailUrl": "https://www.realtor.com/realestateandhomes-detail/6310-Needham-Ln_Austin_TX_78739_M91247-38201","searchLocation": "Austin, TX","sourceUrl": "https://www.realtor.com/realestateandhomes-search/Austin_TX","collectedAt": "2026-08-21T09:14:03.512Z"}
Reliability
Rows come from Realtor.com's own search API, the same endpoint String's production Realtor feeds read, so prices, bed and bath counts, square footage and coordinates arrive as numbers rather than as card text that has to be unpicked.
Several fields are recovered rather than read straight off one key, because Realtor.com stores them
in more than one place depending on how the home is advertised. Bath counts prefer
baths_consolidated so half baths survive; the sold price is only taken from a row whose own status
is sold, since an active listing carries the previous owner's sale in the same field, sometimes
decades old; and the brokerage falls back through office, branding and source-agent names before it
resorts to the broker of record.
A location that cannot be read is recorded in the run's SUMMARY under failures rather than
quietly returning fewer rows, and a run in which every location failed exits with an error. If
Realtor.com rejects a query outright, the error message it gave is carried through into that record.
There are no retries by design. The String Unblocker behind this Actor owns proxy rotation, session reuse and anti-bot solver selection, so a retry loop out here would re-roll the same block.
Limitations
One request per location, capped at 200 listings, because the search API rejects the whole query above roughly that number. It is a broad sample, not a full market crawl: narrow by ZIP code to widen coverage. Photos, listing descriptions, days on market, price history, open-house times, HOA fees and tax records are out of scope, as are agent phone numbers and email addresses. US only.
Non-disclosure states, Texas among them, withhold sold prices. Those rows fall back to the last list price, which is the best figure the source publishes.
How much does it cost?
Pricing is per event: one charge for each result row written to the dataset. A location that fails produces no rows and costs nothing. The current rate is in the pricing panel at the top of this page.
Runs started from an Apify free plan stop at 250 requests and 250 results and say so in the run's
status message; any paid plan runs the full input and whatever maxItems you set. The cap exists
because this Actor fetches through String's own infrastructure, which Apify does not reimburse on
free-plan runs. It binds on requests as well as rows, so a long input list cannot spend those
fetches on rows the run will not return.
Using it with the Apify API
import { ApifyClient } from "apify-client";const client = new ApifyClient({ token: "<YOUR_APIFY_TOKEN>" });const run = await client.actor("usestring/realtor-listings").call({locations: ["Austin, TX", "78704"],listingType: "sold",maxItems: 400});const { items } = await client.dataset(run.defaultDatasetId).listItems();const perSqft = items.filter((row) => row.price && row.areaSqft).map((row) => row.price / row.areaSqft);console.log(perSqft.length, "comps");const summary = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord("SUMMARY");console.log(summary?.value);
Is it legal to scrape Realtor.com?
The Actor reads the public search results a logged-out visitor sees, through the same endpoint the public page uses. There is no account, no session cookie and no paywall. Scraping public web pages is broadly lawful in the US and the EU, and courts have repeatedly declined to treat reading a public page as unauthorised access.
A listing row is property data. The people it can name are the listing agent and the brokerage, which Realtor.com publishes as business contact information for exactly that purpose; no phone numbers or email addresses are collected, and no buyer, seller or tenant details appear. If you use agent names for outreach, that is marketing to a business contact and the usual rules on solicitation apply to you rather than to the data. None of this is legal advice.
Related actors
- Zillow Property Listings Scraper — the same market sweep on Zillow, useful as a cross-check where MLS coverage differs.
- Zillow Property Detail Scraper — year built, home type and the listing description for a specific home.
- LoopNet Commercial Listings Scraper — commercial space instead of homes, for sale or for lease.
- AutoTrader Vehicle Listings Scraper — the same location-to-rows shape applied to used vehicles.
FAQ
Do I need a Realtor.com account, API key or cookies? No. The Actor reads public search results as a logged-out visitor and never signs in.
How many listings do I get per location? Up to 200, which is the most the Realtor.com search accepts in one query. Five locations therefore return up to 1,000 rows for five requests.
Can I get sold homes and rentals?
Yes. listingType: "sold" reads recently sold homes and for_rent reads the rentals surface.
Is price the sold price on a sold listing?
Where Realtor.com discloses it, yes. Non-disclosure states withhold sold prices, and those rows fall
back to the last list price.
Why is baths sometimes a decimal?
Because it is the consolidated count. A home with two full baths and a powder room is 2.5, which
is how buyers compare them.
Which countries does it support?
The United States only. This Actor targets realtor.com and takes no country input.
How fresh is the data?
Every row carries collectedAt and reflects what Realtor.com returned at that moment. Schedule the
Actor to build a time series.
What happens if one location fails?
The rest of the batch still returns, and the failed location plus its error go into the run's
SUMMARY record. Only a run where every location failed exits with an error.
Feedback
Spotted a field parsed wrong, or a location that consistently fails? Open an issue from the Issues tab on this Actor's Store page, with the input that reproduces it.
