Homesnap Scraper - US For-Sale Listings, Prices & Property Data avatar

Homesnap Scraper - US For-Sale Listings, Prices & Property Data

Pricing

from $0.40 / 1,000 listings

Go to Apify Store
Homesnap Scraper - US For-Sale Listings, Prices & Property Data

Homesnap Scraper - US For-Sale Listings, Prices & Property Data

Scrape Homesnap (Homes.com / CoStar) homes for sale: address, price, beds, baths, sqft, lot size, coordinates, MLS id, status, HOA, year built, and photos. Search by place, ZIP, URL, or bounding box; filter by price, beds, baths, size, and property type. HTTP-first, runs on proxies.

Pricing

from $0.40 / 1,000 listings

Rating

0.0

(0)

Developer

Ihor Bielievskiy

Ihor Bielievskiy

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Give it a place name, a ZIP, or a Homesnap city URL and get back clean, structured listings: address, price, beds, baths, square footage, lot size, coordinates, MLS id, listing status, HOA, year built, and photos. Filter by price, beds, baths, size, and property type. Export as JSON, CSV, or Excel.

Homesnap now serves Homes.com / CoStar data. This actor calls Homesnap's own JSON listing API directly instead of driving a headless browser, so it's fast.

Use a US residential proxy. The Homesnap listing API serves degraded (empty) results to non-US and datacenter IPs — Count comes back 0 even for big markets. From a US residential IP it returns the real inventory. The default proxy config is US residential for exactly this reason; leave it on unless you know what you're doing.

What it can scrape

Set listingType:

  • for_sale — active for-sale listings (the default)
  • under_contract — listings under contract / pending
  • sold — recently sold homes

Tell it where to look in whichever way is easiest:

  • search — a list of place names or ZIPs, e.g. "Austin, TX" or "10028".
  • startUrls — Homesnap for-sale city URLs straight from the address bar.
  • cities — a list of { state, city } objects.
  • boundingBox — a raw map viewport (north / south / east / west) for full manual control.

Each location is resolved to its Homesnap area and the listings inside its bounding box are returned (up to 500 per location — the API's own viewport cap).

Filtering and sorting

All filters run on the actor side after the fetch, so they compose cleanly:

FilterMeaning
priceMin / priceMaxPrice range in USD.
bedsMinMinimum bedrooms.
bathsMinMinimum bathrooms (half-baths count as 0.5).
sqftMin / sqftMaxInterior size range.
propertyTypesKeep only these type codes: 1 single family, 2 condo, 3 townhouse, 4 co-op, 5 multi-family, 6 land, 7 manufactured, 8 commercial.
sortByprice_asc, price_desc, newest, beds_desc, or sqft_desc (applied per location).

Input

FieldDescription
searchList of place names or ZIPs to resolve and scrape.
startUrlsHomesnap for-sale city URLs (/homes-for-sale/{City}/{State}).
citiesList of { state, city } objects.
boundingBoxOptional raw viewport { north, south, east, west } in decimal degrees.
listingTypefor_sale, under_contract, or sold.
propertyTypesOptional list of property-type codes (see table above).
priceMin / priceMaxPrice range filter.
bedsMin / bathsMinMinimum beds / baths filter.
sqftMin / sqftMaxSize range filter.
sortByResult ordering within each location.
maxItemsStop after this many results across all locations (0 = no limit).
proxyConfigurationApify Proxy — see the coverage note at the top.
impersonateBrowser TLS fingerprint (chrome by default).
{
"search": ["Austin, TX"],
"listingType": "for_sale",
"priceMin": 300000,
"priceMax": 900000,
"bedsMin": 3,
"propertyTypes": [1, 3],
"sortBy": "price_asc",
"maxItems": 200
}

Output fields

FieldTypeNotes
listing_id / property_idintHomesnap identifiers (used for dedupe).
mls_id / mls_numberstr / intMLS source number and id.
statusstrHuman label: for_sale, under_contract, sold, off_market.
listing_status_code / mls_status_codeintRaw status codes.
transaction_type / transaction_type_labelint / strCode plus for_sale / for_rent when known.
address, unit, city, state, zip_codestrAddress parts.
price, original_pricefloatUSD.
price_per_sqftfloatprice / sqft, when both present.
beds, baths, baths_full, baths_halfint / floatbaths counts half-baths as 0.5.
sqft, lot_sizeint / floatInterior sqft and lot size.
year_built, unit_countint
property_type / property_type_labelint / strCode plus label (single_family, condo, …) when known.
property_subtypeintRaw subtype code.
days_on_marketint
list_date / list_date_isoint / strEpoch ms and ISO-8601 UTC.
hoa_fee, hoa_frequencyfloat / str
lat, lngfloatCoordinates.
url, building_namestr
photo_urlslist[str]CoStar CDN URLs, sized to 1024x768.
detailsstrListing remarks when present.

Rows that fail to resolve or parse are emitted as typed error records (error, error_type, area_id, detail, source_url) instead — never silently dropped.

Example output

{
"listing_id": 227047402,
"property_id": 400029947475,
"mls_id": "RLS20099639",
"status": "for_sale",
"transaction_type": 1,
"transaction_type_label": "for_sale",
"address": "205 E 85th Street #THA",
"unit": "THA",
"city": "New York",
"state": "NY",
"zip_code": "10028",
"price": 7295000.0,
"price_per_sqft": 2206.59,
"beds": 3,
"baths": 4.0,
"sqft": 3306,
"lot_size": 0.0,
"year_built": 2009,
"property_type": 2,
"property_type_label": "condo",
"list_date": 1717200000000,
"list_date_iso": "2024-06-01T00:00:00+00:00",
"hoa_fee": 4749.0,
"hoa_frequency": "Monthly",
"lat": 40.777978,
"lng": -73.953811,
"building_name": "The Brompton",
"url": "https://www.homesnap.com/NY/New-York/205-E-85th-Street/property/400029947475",
"photo_urls": ["https://ahprd1cdn.csgpimgs.com/i2/.../1024x768/image.jpg"]
}

How it works

Two calls per city:

  1. POST /service/Misc/Search resolves the city text to its Homesnap area (id + bounding box + state).
  2. POST /service/Listings/Search returns the for-sale listings inside that bounding box, capped at maximumListings (max 500). The request carries the X-CoStar-Brand header and the criteria envelope the site's map uses.

Photos come straight from the listing payload (CoStar CDN), so there's no extra request per home; the {size} slot is filled in for you.

A few things worth knowing

  • US residential proxy. Covered at the top — without one, non-US / datacenter IPs get empty results. The default config handles this.
  • 500 listings per location. That's the API's map-viewport cap, not the actor. For full coverage of a dense metro, scrape it by neighborhood / smaller cities, or pass tighter boundingBox viewports.
  • Nothing fails silently. If a city can't be resolved or a request is rejected (e.g. the API contract changes → HTTP 422), you get a typed error row for it (with the error class in error_type). If every location comes back empty or failed while a proxy is configured — the signature of a non-US/datacenter soft-block — the whole run is marked failed with a clear message instead of finishing green with zero items. So an empty successful run means "nothing found", never a hidden block.
  • You're billed per valid listing delivered, so error rows and duplicates don't cost you anything.

Notes

Only public, unauthenticated Homesnap pages are scraped. The data comes from Homesnap's public site (Homes.com / CoStar); follow their Terms and the laws that apply to you, and use it responsibly. Removal requests are honored.

Who built this

I build scrapers for my own projects and publish the ones that turn out genuinely useful. If you need a custom scraper, a data pipeline, or a change to this actor, I'm available for freelance work.

GitHub: github.com/bujhmml · Site: bujhmml.fun