Apartments.com URL | Keyword | Rich Output
Pricing
from $1.50 / 1,000 results
Apartments.com URL | Keyword | Rich Output
From $1.5/1K. Extract Apartments.com rental listings at lower cost. Search by city, ZIP, neighborhood, or address, paste result/property URLs, or use autocomplete. Get rent, floorplans, units, amenities, fees, schools, transit, ratings, reviews, photos, phone, and GPS data.
Pricing
from $1.50 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
0
Monthly active users
4 days ago
Last modified
Categories
Share
Apartments.com Scraper
Pull rental listings from Apartments.com at a fraction of the usual cost. Search any city, ZIP, neighborhood, or street address; paste result and property links; or get location autocomplete suggestions. Every property comes back as one rich row with rent, floorplans, available units, amenities, policies, fees, schools, transit, walk score, ratings, reviews, photos, phone, and GPS coordinates.
Why this scraper
- One row per property, not one row per sub-block. Many scrapers split a single property into a dozen or more rows (info, amenities, fees, schools, reviews, photos, and so on) and bill you for each. This actor returns the whole property as a single nested record, so the same data costs you far less.
- 50+ fields per property, including floorplan models, every available unit with rent and square footage, full amenity list, pet and parking policy, fee schedule, nearby schools, walk and transit scores, office hours, ratings, and recent reviews.
- Three modes: location search, URL scraping, and location autocomplete.
- One rich row per property means more usable data per result, so you pay for properties, not fragments.
- Datacenter proxy friendly. The default connection works out of the box and keeps your proxy spend low, with automatic recovery if a page is momentarily refused.
- Graceful pagination that walks the whole result set by default (no artificial page cap), bounded only by the
maxListingstotal cap so runs stay predictable, with duplicate properties removed. - Daily/recurring change monitoring: turn on Incremental mode to get only NEW, UPDATED, and REAPPEARED properties on every scheduled run, or resume one specific interrupted crawl with
resumeFromRunId.
Data you get
Sample shape, values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
| id | abc1234 |
| name | Sample Apartments |
| url | https://www.apartments.com/sample-apartments-austin-tx/abc1234/ |
| address | 100 Example St, Austin, TX 78701 |
| city / state / zip | Austin / TX / 78701 |
| latitude / longitude | 30.0000 / -97.0000 |
| rentMin / rentMax | 1200 / 2600 |
| currency | USD |
| bedsLabel | Studio - 2 Beds |
| bedsRange / bathsRange / sqftRange | 1 - 2 bd / 1 - 2 ba / 500 - 1,000 |
| propertyType | apartment |
| yearBuilt / unitsInBuilding / stories | 2010 / 200 / 4 |
| neighborhood | Sample Neighborhood |
| leaseOptions | 6 - 15 Month Leases |
| managementCompany | Sample Management Co |
| rentSpecial | Move-in special: one month free |
| verified | true |
| phone | (800) 000-0000 |
| petsAllowed | true |
| rating / reviewCount | 4.1 / 0 |
| parking | ["Garage - $0/mo", "Covered Lot - $0/mo"] |
| transit | [{ "name": "Sample Station", "distanceMiles": 1.0, "driveTimeMin": 5 }] |
| amenities | ["Pool", "Fitness Center", "In Unit Laundry"] |
| floorplans | [{ "name": "A1", "rent": "$1,200 - $1,400", "beds": 1, "baths": 1, "sqft": 650 }] |
| units | [{ "model": "A1", "unit": "000", "beds": 1, "baths": 1, "rent": 1300, "sqft": 650, "availability": "Now" }] |
| fees | ["Application Fee $0", "Admin Fee $0"] |
| schools | [{ "name": "Example Elementary", "type": "Public", "grades": "PK-5", "students": 500 }] |
| walkScore | { "walk": 80, "transit": 50, "drive": 90, "bike": 70 } |
| officeHours | ["Monday, Tuesday, Wednesday, Thursday, Friday: 09:00-18:00"] |
| reviews | [{ "author": "A. Renter", "title": "Great place", "body": "Sample review text.", "date": "2026-01-01" }] |
| photos | ["https://images1.apartments.com/i2/0000/sample-photo.jpg"] |
| changeType | NEW (incremental mode only — see "Resume & recurring updates" below) |
| changedFields | ["rentMax"] (incremental mode, UPDATED rows only) |
| firstSeenAt | 2026-01-01T00:00:00.000Z (incremental mode only) |
| lastSeenAt | 2026-01-02T00:00:00.000Z (incremental mode only) |
In autocomplete mode each row is a location suggestion with id, display, geographyType, city, state, latitude, longitude, and boundingBox. Incremental mode does not apply to autocomplete.
How to use
Search a city, fast cards only:
{"mode": "search","locations": ["Austin, TX"],"fetchDetails": false,"maxPages": 3,"maxListings": 100}
Search with filters and full details:
{"mode": "search","locations": ["Denver, CO", "80202"],"propertyType": "apartments","bedrooms": "2","minRent": 1500,"maxRent": 2800,"fetchDetails": true,"maxPages": 5}
Scrape URLs (result pages and property pages, mixed):
{"mode": "url","urls": ["https://www.apartments.com/houston-tx/2-bedrooms/","https://www.apartments.com/the-grove-houston-tx/9cwjc35/"],"fetchDetails": true,"maxPages": 2}
Location autocomplete:
{"mode": "autocomplete","locations": ["Brooklyn", "78701"]}
Resume & recurring updates
There are two different things here — pick the one that matches what you're doing:
| Need | Use |
|---|---|
| A crawl stopped and should continue | resumeFromRunId / automatic checkpoint recovery |
| Run the same search every day and receive only changes | incrementalMode |
| Keep separate daily campaigns for similar searches | distinct stateKey values |
| Run a normal full snapshot | leave both off |
Resume (resumeFromRunId) continues one specific interrupted or previous large crawl: paste a run ID or dataset ID and this run skips properties already collected there, returning only the remaining new properties. An automatic same-run checkpoint also protects against platform migrations/resurrects without any input needed.
Incremental mode (incrementalMode) is for a schedule (for example, daily): the actor remembers the previous run of the same search by itself, so you never paste a run ID. The first run returns everything as NEW. Later runs return only NEW, UPDATED, and REAPPEARED properties by default — duplicates and unchanged properties are suppressed. Turn on emitUnchanged or emitExpired only when you also want those rows returned (and billed for). State is isolated per location/URL, property type, bedrooms, rent range, lifestyle, and detail-mode setup automatically; set stateKey to name or deliberately share a monitoring campaign.
Scheduled-run example — same search, run daily:
Day 1 (first run ever for this search):
{ "mode": "search", "locations": ["Austin, TX"], "incrementalMode": true }
→ every property comes back with "changeType": "NEW".
Day 2 (the schedule fires again, identical input):
{ "mode": "search", "locations": ["Austin, TX"], "incrementalMode": true }
→ properties that vanished or reappeared come back as "changeType": "REAPPEARED", properties whose rent/etc. changed come back as "changeType": "UPDATED" with changedFields listing what changed, brand-new listings come back as "changeType": "NEW" — and properties that are still there, unchanged, are not returned at all (suppressed) unless emitUnchanged is on.
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| mode | string | search | search, url, or autocomplete. |
| locations | array | ["Austin, TX"] | City, ZIP, neighborhood, or address terms. Used by search and autocomplete. |
| propertyType | string | any | any, apartments, houses, condos, townhomes. |
| bedrooms | string | any | any, studio, 1, 2, 3, 4 (minimum beds). |
| minRent | integer | (none) | Lowest monthly rent in USD. |
| maxRent | integer | (none) | Highest monthly rent in USD. |
| lifestyle | string | none | Single lifestyle filter (for example pet-friendly, luxury, furnished). Applied when property type is any. |
| urls | array | (example) | Apartments.com result or property URLs. Used by url mode. |
| fetchDetails | boolean | true | Enrich each property with its detail page. Turn off for fast card-only runs. |
| maxListings | integer | 20 | The sole soft cap on the run, applied across all locations/URLs. 0 means unlimited. |
| maxPages | integer | 0 | Safety bound on result pages walked per location or start URL (about 40 properties per page). 0 (default) means unlimited: the walk stops on its own once a page comes back empty or repeats properties already collected, or sooner once maxListings is reached. Set a number only for an explicit page cap below that natural stop. |
| resumeFromRunId | string | (none) | Continue one specific previous run/dataset: properties already saved there are loaded before scraping starts and skipped, so this run only appends new properties. For recurring daily monitoring of the same search, use incrementalMode instead — see "Resume & recurring updates" above. |
| incrementalMode | boolean | false | Daily/recurring monitoring of this same search. First run returns everything as NEW; later runs return only NEW/UPDATED/REAPPEARED by default. See "Resume & recurring updates" above. |
| stateKey | string | (none) | Optional name for a monitoring campaign, so its incremental state stays stable or is deliberately shared. Auto-derived from your search/filter/detail settings when left empty. |
| emitUnchanged | boolean | false | Incremental mode only. Also return properties unchanged since the last run, marked UNCHANGED. Adds and bills extra rows you already have. |
| emitExpired | boolean | false | Incremental mode only. Also return properties from a previous run no longer found, marked EXPIRED, once a run has fully scanned the search (not capped, not a resume). Adds and bills extra synthetic rows. |
| proxy | object | Apify Datacenter | Connection settings. |
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape — the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record — not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Walking the whole catalogue
By default maxPages is 0 (unlimited): a search or URL entry walks every result page until Apartments.com naturally runs out — an empty page, or a page that keeps repeating properties already collected — or until maxListings (the run's only soft cap, default 20, set 0 for unlimited) is reached, whichever comes first. Set maxPages to a number only when you want an explicit page cap below that natural stop.
For a very large walk-all pull, use resumeFromRunId in a follow-up run instead of starting over: paste the ID of a previous run (or its dataset) and this run loads the properties it already saved, skips them, and appends only new properties to a fresh dataset. Leave it empty for a normal run.
The actor also checkpoints its own progress internally, so if a run is interrupted by a platform migration it picks back up without re-saving (and re-charging for) properties it already wrote.
Output example
Sample shape, values are illustrative placeholders, not from a live listing.
{"id": "abc1234","url": "https://www.apartments.com/sample-apartments-austin-tx/abc1234/","name": "Sample Apartments","address": "100 Example St, Austin, TX 78701","city": "Austin","state": "TX","zip": "78701","latitude": 30.0000,"longitude": -97.0000,"rentMin": 1200,"rentMax": 2600,"currency": "USD","bedsLabel": "Studio - 2 Beds","bedsRange": "1 - 2 bd","bathsRange": "1 - 2 ba","sqftRange": "500 - 1,000","propertyType": "apartment","yearBuilt": 2010,"unitsInBuilding": 200,"stories": 4,"neighborhood": "Sample Neighborhood","leaseOptions": "6 - 15 Month Leases","managementCompany": "Sample Management Co","rentSpecial": "Move-in special: one month free","verified": true,"phone": "(800) 000-0000","petsAllowed": true,"rating": 4.1,"reviewCount": 0,"parking": ["Garage - $0/mo"],"transit": [{ "name": "Sample Station", "distanceMiles": 1.0, "driveTimeMin": 5 }],"amenities": ["Pool", "Fitness Center", "In Unit Laundry"],"floorplans": [{ "name": "A1", "rent": "$1,200 - $1,400", "beds": 1, "baths": 1, "sqft": 650 }],"units": [{ "model": "A1", "unit": "000", "beds": 1, "baths": 1, "rent": 1300, "sqft": 650, "availability": "Now" }],"fees": ["Application Fee $0"],"schools": [{ "name": "Example Elementary", "type": "Public", "grades": "PK-5", "students": 500 }],"walkScore": { "walk": 80, "transit": 50, "drive": 90, "bike": 70 },"officeHours": ["Monday, Tuesday, Wednesday, Thursday, Friday: 09:00-18:00"],"reviews": [{ "author": "A. Renter", "title": "Great place", "body": "Sample review text.", "date": "2026-01-01" }],"photos": ["https://images1.apartments.com/i2/0000/sample-photo.jpg"],"detailScraped": true,"scrapedAt": "2026-01-01T00:00:00.000Z"}
Plan requirement
Apify Residential proxy is the default and the most reliable option: the actor automatically varies the connection across many regions and falls back to an alternate network when one is busy, so runs stay stable at any scale. Residential requires a paid Apify plan (Starter or higher). On the free plan, or to lower cost, switch to Apify Datacenter in the connection settings: it works well when connections are healthy and still falls back to the alternate network otherwise. Apartments.com shows the same United States listings regardless of the connecting region, so the regional variety is purely for reliability. The actor also recovers automatically if a page is momentarily refused, so one refused page does not stop the run.