US Rentals Scraper - Apartments.com & Realtor.com
Pricing
from $2.00 / 1,000 results
US Rentals Scraper - Apartments.com & Realtor.com
Scrape US rental listings from Apartments.com and Realtor.com in one run. Returns address, coordinates, rent range, beds, baths, square feet, property type, year built, pet policy, amenities, floor plans, photos, leasing phone and days on market. Search by city, ZIP or listing URL.
Pricing
from $2.00 / 1,000 results
Rating
0.0
(0)
Developer
Thirdwatch
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
US Rentals Scraper — Apartments.com & Realtor.com
Export US rental listings from the two largest public rental marketplaces in a single run. Give the Actor a city, a ZIP code, or a listing URL and it returns one clean, normalised row per property — address, coordinates, rent range, beds, baths, square feet, property type, year built, pet policy, amenities, per-unit floor plans, photos, the leasing or broker contact, days on market, status, and the canonical listing URL.
Both sources come back in one dataset with a source field on every row, so you can query
Apartments.com and Realtor.com together or keep them apart. Rows are de-duplicated by
listing id within a run.
Every row is normalised the same way regardless of which site it came from: prices and
areas are numbers (never strings), coordinates are floats, dates are ISO 8601 UTC, URLs are
absolute, currency is explicit, and the query that produced the row is stamped on it as
source_query.
What you get
| Use case | How to run it |
|---|---|
| Rent comps for a submarket — what a 1-bed actually rents for on a given block | Feed a list of ZIP codes, set minBeds: 1 and maxBeds: 1, then group price_min/price_max by zip_code. The floorplans array gives per-unit rent, bed, bath and square-foot detail for community properties, so you can build a real distribution instead of averaging headline rents. |
| Lead lists for property-management and proptech sales | Run source: apartments across your target metros, keep phone, listing_name, address and broker_name, and filter to communities with many floorplans (larger portfolios). Apartments.com exposes the leasing-office phone directly on the search page, so this needs no detail-page spend. |
| Renter-facing search and alerting | Run the same query on a schedule with source: both, filter with minPrice/maxPrice/minBeds, and diff against your last dataset on listing_id. days_on_market and specials (concessions like "2 Months Free") tell you which listings are going stale and where the landlord is discounting. |
Input
Only queries is required. Everything else has a sensible default.
{"queries": ["Austin, TX", "78704", "https://www.apartments.com/the-watson-austin-tx/s286zb6/"],"source": "both","maxResults": 50,"includeDetails": false,"minPrice": 1200,"maxPrice": 3000,"minBeds": 1,"maxBeds": 2,"minBaths": 1,"propertyTypes": ["apartments", "houses"],"proxyConfiguration": { "useApifyProxy": true, "apifyProxyCountry": "US" }}
| Field | Type | Default | Meaning |
|---|---|---|---|
queries | array of strings | (required) | One entry per search. Accepts a city and state (Austin, TX), a bare ZIP code (78704), an Apartments.com or Realtor.com search URL, or a single listing URL (scraped as one detailed row). |
source | apartments | realtor | both | both | Which site(s) to scrape. A site-specific URL in queries is always sent to that site only, whatever this is set to. |
maxResults | integer 1–1000 | 50 | Listings per query per source. With source: both, 15 returns up to 30 rows per query. |
includeDetails | boolean | false | Visit each listing page to add year built, the full description, the complete photo set and amenity list, pet policy, per-unit floor plans, and the contact phone. Slower and more expensive. |
maxDetailPages | integer | all | Caps how many listings get the detail visit when includeDetails is on. |
minPrice / maxPrice | integer | — | Monthly rent window in USD. Applied as a site filter where supported and re-checked on every row before it is saved. A listing whose rent range overlaps the window is kept. |
minBeds / maxBeds | integer 0–8 | — | Bedroom range. Use 0 to include studios. |
minBaths | integer 0–8 | — | Minimum bathrooms. |
propertyTypes | array | all | Any of apartments, houses, condos, townhomes. |
proxyConfiguration | object | US datacenter | See Proxies and blocking below. |
Searching by ZIP code
Apartments.com has no bare-ZIP search URL, so a five-digit query is resolved to its city and
state first and searched as city-st-zip. Realtor.com takes the ZIP directly. Results for a
ZIP query can include listings in immediately adjacent ZIPs — that is the sites' own
behaviour, and every row carries its true zip_code so you can tighten the set yourself.
Getting past the pagination ceiling
Both sites cap how deep a single search paginates (about 1,080 listings on Apartments.com,
about 2,100 on Realtor.com). To pull a whole metro, pass several ZIP codes or neighbourhood
names as separate queries rather than one large city.
Output
One row per listing. Search-only mode fills everything the search page carries; the fields
marked detail are populated when includeDetails is on (or when you pass a listing URL
directly).
| Field | Type | Notes |
|---|---|---|
listing_id | string | Stable per site. De-duplication key, namespaced by source. |
source | string | apartments or realtor. |
source_query | string | The queries entry that produced this row. |
listing_url | string | Canonical, absolute listing URL. |
listing_name | string | Property or community name. |
address | string | Full one-line address. |
street | string | Street line only. |
city | string | |
state | string | Two-letter code. |
zip_code | string | |
latitude | float | |
longitude | float | |
price | integer | null | Set only when the listing has one rent, not a range. |
price_min | integer | null | Low end of the advertised rent. |
price_max | integer | null | High end of the advertised rent. |
price_formatted | string | Display string, e.g. $1,615 - $4,884. |
currency | string | Always USD. |
beds / beds_min / beds_max | number | null | 0 means studio. |
baths / baths_min / baths_max | number | null | Apartments.com: detail. |
square_feet / square_feet_min / square_feet_max | integer | null | Apartments.com: detail. |
property_type | string | apartment, house, condo, townhome, … |
year_built | integer | null | detail |
pet_policy | object | null | Apartments.com: {"pets_allowed": true}. Realtor.com: {"cats": …, "dogs": …}. |
amenities | array of strings | Short list on search, full list on detail. |
floorplans | array of objects | {name, beds, baths, square_feet, price, price_min, price_max, availability} per unit or plan. |
photos | array of strings | Search pages carry only the thumbnails: 1 photo on Apartments.com, ~3 on Realtor.com. Turn on includeDetails for the full gallery (typically 18–40). |
photo_count | integer | Length of photos. |
agent_name | string | Realtor.com, where a named agent is listed. |
broker_name | string | Realtor.com management or brokerage office. |
phone | string | Apartments.com: leasing office, on search. Realtor.com: detail. |
list_date | string | ISO 8601. Realtor.com only. |
days_on_market | integer | null | Derived from list_date. Realtor.com only. |
listing_status | string | e.g. for_rent. |
specials | string | Concessions, e.g. 2 Months Free. |
description | string | detail, up to 4,000 characters. |
scraped_at | string | ISO 8601 UTC. |
Sample row (abridged)
{"listing_id": "s286zb6","source": "apartments","listing_url": "https://www.apartments.com/the-watson-austin-tx/s286zb6/","listing_name": "The Watson","address": "11901 Burnet Rd, Austin, TX 78758","city": "Austin", "state": "TX", "zip_code": "78758","latitude": 30.40504, "longitude": -97.71511,"price_min": 1615, "price_max": 4884, "price_formatted": "$1,615 - $4,884","currency": "USD","beds_min": 0.0, "beds_max": 2.0, "baths_min": 1.0, "baths_max": 2.0,"square_feet_min": 425, "square_feet_max": 1403,"property_type": "apartment", "year_built": 2026,"pet_policy": {"pets_allowed": true},"amenities": ["Pool", "Fitness Center", "Rooftop Deck"],"floorplans": [{"name": "S1WF", "beds": 0, "baths": 1, "square_feet": 434, "price": 1615}],"photo_count": 18,"phone": "+1-832-730-2535","specials": "2 Months Free","listing_status": "for_rent","scraped_at": "2026-09-07T22:04:48+00:00"}
What each source does and does not carry
These are limits of the sites, not of the Actor:
- Apartments.com has no listing agent, broker or list date, so
agent_name,broker_name,list_dateanddays_on_marketstay empty. The leasing-officephoneis the contact, and it is available without a detail visit. - Apartments.com search results carry rent and bedrooms but not bathrooms, square feet,
year built or the description — turn on
includeDetailsfor those. - Realtor.com search cards carry no phone number; turn on
includeDetailsto get it. - For a multi-unit community, the singular
price,beds,bathsandsquare_feetarenullby design — a community has a range, not one value. Use the_min/_maxpair, orfloorplansfor per-unit numbers.
Proxies and blocking
Both sites are protected, at different strengths. Measured 2026-09-07, three requests per cell against an Austin, TX search:
| Source | Datacenter US | Residential US | Apify Unblocker |
|---|---|---|---|
| Apartments.com (iOS app User-Agent) | 3/3 OK | 3/3 OK | 3/3 OK |
| Apartments.com (desktop Chrome User-Agent) | — | 0/3 (403, 388-byte "Access Denied") | — |
| Realtor.com (desktop Chrome User-Agent) | 0/3 (429) | 0/3 (429) | 3/3 OK |
So the Actor runs Apartments.com on the cheap US datacenter pool and automatically
escalates to US residential only if datacenter starts getting denied, and Realtor.com
through the Apify Unblocker, which is the only route that is not rate-limited. Pin a group
in proxyConfiguration and the Actor uses exactly that pool with no escalation; supply your
own proxyUrls and they are used verbatim. Apartments.com serves US IPs only.
No browser is used for either source — this is a pure HTTP Actor running in 256 MB.
Zero results are honest
A run that returns nothing tells you why. If a source answered with a real listings page that simply had no matches, the run succeeds with a status message asking you to widen the filters. If the source never answered with a parseable page — blocked, rate-limited, or serving a challenge — the run fails with a message naming the blocked source. A block is never reported as "no listings found".
Legal
Scrapes only publicly available listing pages. No login, no paywall, and no personal data beyond the business contact details the sites publish on the listing itself. You are responsible for how you use the output, including compliance with fair-housing rules when listing data is used in advertising or tenant screening.