Realtor.com Listings Scraper avatar

Realtor.com Listings Scraper

Pricing

from $0.75 / 1,000 results

Go to Apify Store
Realtor.com Listings Scraper

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

String

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

15 days ago

Last modified

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
  • agentName and brokerName on every row, which no other surface of the page publishes together
  • baths is Realtor.com's consolidated count, so a home with two full baths and a powder room reads as 2.5 rather than 2
  • On a sold row, price is 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?

FieldTypeDescription
propertyIdstringRealtor.com's own property ID, stable across runs. Use it to de-duplicate
addressstringStreet line
citystringCity
statestringTwo-letter state code
zipcodestringPostal code
pricenumberSold price on a sold row, otherwise the list price
bedsnumberBedroom count
bathsnumberConsolidated bathroom count, e.g. 2.5
areaSqftnumberLiving area in square feet
lotSizeSqftnumberLot size in square feet
statusstringfor_sale, ready_to_build, for_rent or sold
agentNamestringListing agent, where Realtor.com names one
brokerNamestringBrokerage or office as the listing displays it
latitudenumberDecimal degrees
longitudenumberDecimal degrees
detailUrlstringLink to the Realtor.com listing page
searchLocationstringThe location from your input that produced this row
sourceUrlstringThe human Realtor.com search page for that location
collectedAtstringISO 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, areaSqft and lotSizeSqft together, 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 default for_sale search 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

  1. Open the Actor and click Try for free, or add it to your Apify account.
  2. Enter locations in the Locations field, one per line. Austin, TX and 78704 are both valid; a city without its state is ambiguous and may resolve somewhere you did not intend.
  3. Choose a Listing type from the dropdown: for_sale, for_rent or sold.
  4. Optionally lower Maximum results. A value below 200 also narrows each request, so it saves time as well as spend.
  5. Click Start. One location is one request, so even twenty markets finish quickly.
  6. Export from the Dataset tab as JSON, CSV or Excel, and read the run's SUMMARY record for any location that failed.

Input

FieldTypeDefaultDescription
locationsarray of stringsrequiredCities with state ("Austin, TX") or ZIP codes. Between 1 and 100 entries. Duplicates collapse to one request
listingTypestringfor_saleOne of for_sale, for_rent, sold. for_sale also returns ready_to_build new construction
maxItemsinteger1000Ceiling on dataset rows, 1 to 50000. Below 200 it also narrows the per-location request
concurrencyinteger2Locations 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);

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.

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.