# Apartments.com Scraper $1/1K💰 | Rent Listings | US Rental Data (`ahmed_jasarevic/apartments-scraper`) Actor

Extract US rental listings from Apartments.com without an official API key. Get rent prices, beds/baths, square footage, addresses and leasing-office phones for rent comps, rental market research and apartment price monitoring.

- **URL**: https://apify.com/ahmed\_jasarevic/apartments-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Apartments.com Scraper — US Rental Listings Data

Extract **US rental listings from Apartments.com** — property name, address, rent prices, beds/baths, square footage, and leasing-office phone — **without an official API key**. Built for rental market research, rent comps, apartment price monitoring, and property management lead generation.

### Main Use Cases

- **Rental market research** — build city-level datasets of active US rental listings
- **Rent comps** — collect asking rents, unit sizes, and specs for comparable analysis
- **Apartment price monitoring** — track rent changes over time with scheduled runs
- **Property management lead generation** — collect leasing-office phone numbers and property brands
- **Apartment hunting & relocation data** — shortlist apartments in a new city, by ZIP, or by bedroom count
- **Multifamily portfolio benchmarking** — compare rent, size, and amenities across markets

### How It Works

Apartments.com is protected by **Akamai Bot Manager**. This actor fetches Apartments.com search result pages with a TLS-fingerprinting HTTP client routed through rotating **US residential proxies** — no browser needed for most runs. When Akamai flags a session, the actor rotates to a fresh IP and retries; page 1 (the hardest page) gets a double IP hunt. An **opt-in Playwright/Firefox browser seed** can take over page 1 when HTTP hunting is exhausted, then hand the trusted session back to the cheap HTTP path.

Give it a city (`charlotte nc`), a ZIP (`10001`), a state, or a pasted search URL, and get a clean JSON dataset back in a couple of minutes.

### Extract US Rental Listings Without an Official Apartments.com API

Apartments.com (CoStar) has **no public developer API**. Its customer API is restricted to authenticated property managers (review retrieval and listing management for their own properties) and requires OAuth credentials a data buyer cannot obtain. This actor reads public listing data directly from search result pages — no key, no registration, no API contract.

### Build Rental Market Research Datasets for Rent Comps

Each run returns one clean JSON object per listing — property name, full address, rent range, beds/baths, square footage, GPS coordinates, and contact phone. Export as JSON, CSV, Excel, or HTML, filter by city/state/ZIP, and feed straight into spreadsheets, BI tools, or pricing models.

### Monitor Rent Prices With Scheduled Runs

Set up a daily or weekly schedule in the Apify console (or call the run API from your own scheduler) to keep a rolling history of asking rents, availability, and new listings per market — the data fuel for price-monitoring dashboards and rental trend reports.

### Input

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `startUrls` | array | No\* | — | Apartments.com search result URLs; filters in the URL are preserved. Used when `search` is empty. |
| `search` | string | No\* | — | Location string — city, state, or ZIP (e.g. `charlotte nc`, `10001`). Builds the search URL automatically. |
| `maxItems` | integer | No | 50 | Max listings per search. Pages are auto-counted (~40/page, fetched in parallel). Apartments.com caps a search at ~720. |
| `proxyConfiguration` | object | No | `{useApifyProxy: true}` | Use the Apify proxy pool. |
| `proxyGroup` | string | No | `AUTO` | Apify proxy pool: `AUTO`, `RESIDENTIAL`, or `DATACENTER` (availability varies). |
| `proxyCountry` | string | No | `US` | Proxy country to pin. US residential IPs clear Apartments.com best. |
| `proxyUrls` | array | No | — | Optional custom residential proxy URLs (own provider). |
| `maxProxyRotations` | integer | No | 8 | Fresh proxy IPs to try per request before giving up (page 1 gets double). |
| `browser` | string | No | `firefox144` | Browser fingerprint: `firefox`, `firefox144`, `firefox135`, `firefox133`, `firefox128`, `chrome`, `chrome142`, `chrome136`, `chrome131`, `chrome124`. |
| `browserSeed` | boolean | No | false | Opt-in: if page 1 stays blocked after the HTTP hunt, load it in a real Playwright/Firefox browser and reuse its trusted session for pages 2+. Adds ~15 s and 1024 MB. |
| `browserSelfTest` | boolean | No | false | Debug tool: launch the browser against the first URL and exit, to check if a browser can clear the current IP. |

\* One of `search` or `startUrls` is required — a run with neither fails.

Filtered search URLs are preserved, e.g.:

```
https://www.apartments.com/charlotte-nc/2-bedrooms/3-1-1-floorplans/
https://www.apartments.com/brooklyn-ny/
https://www.apartments.com/10001/
```

### Output

Each dataset row is one listing card from a search page:

```json
{
  "listingId": "mnxn0r4",
  "url": "https://www.apartments.com/the-vue-charlotte-nc/mnxn0r4/",
  "propertyName": "The Vue",
  "address": "700 N Church St, Charlotte, NC 28202",
  "street": "700 N Church St",
  "city": "Charlotte",
  "state": "NC",
  "zip": "28202",
  "latitude": null,
  "longitude": null,
  "rentMin": null,
  "rentMax": null,
  "rentText": "$1,850",
  "beds": 2,
  "baths": 2,
  "sqft": 980,
  "contactPhone": "(980) 555-0100",
  "page": 1,
  "searchUrl": "https://www.apartments.com/charlotte-nc/",
  "scrapedAt": "2026-09-11T12:10:35.039Z"
}
```

You can download the dataset in **JSON, CSV, HTML, Excel, or XML** from the Dataset tab.

| Field | Description |
|---|---|
| `listingId` | Apartments.com listing identifier |
| `propertyName` | Property name |
| `street` / `city` / `state` / `zip` | Address breakdown |
| `latitude` / `longitude` | GPS coordinates (when present on the search card) |
| `rentText` / `rentMin` / `rentMax` | Rent shown on the card |
| `beds` / `baths` / `sqft` | Unit size |
| `contactPhone` | Leasing office phone |
| `page` / `searchUrl` | Where the listing came from |
| `scrapedAt` | ISO timestamp |

### Example Input

```json
{
  "search": "charlotte nc",
  "maxItems": 100
}
```

Filtered search URL mode:

```json
{
  "startUrls": [{ "url": "https://www.apartments.com/brooklyn-ny/2-bedrooms/" }],
  "maxItems": 50
}
```

### Example Output

See the sample record in the [Output](#output) section — a realistic listing from the Charlotte, NC search feed.

### Integrations & Automation

- **Apify API** — trigger runs programmatically from any stack (`POST /v2/acts/{actorId}/runs`)
- **Scheduling** — daily/weekly/monthly runs for price monitoring and market feeds
- **Webhooks & integrations** — Zapier, Make, and other tools via the Apify platform
- **Export** — JSON, CSV, Excel, HTML, XML directly from the Dataset tab

Recommended schedule: **weekly** for market research feeds, **daily** for active rent price monitoring.

### Cost Estimation

Pay-per-result: **$0.001 per listing** (primary event) plus a **$0.00005** start fee. A typical 50-listing run costs around **$0.05** and finishes in ~2 minutes; **1,000 listings ≈ $1**. Free-tier Apify accounts are capped at 10 items per run; paid accounts run unlimited.

**Headline caveat:** Apartments.com is protected by **Akamai Bot Manager**. The **first page** of a search is the hardest — it has no trusted session to reuse, so it depends on finding a clean IP. The actor hunts twice as hard for page 1 (`maxProxyRotations` × 2), then offers the **browser seed** as a final fallback. If Akamai blocks at the **IP level** ("Access Denied" / Reference #), no browser can bypass that — a retry on a different pool usually clears it.

### Tips and Advanced Options

- **Use filtered search URLs** — `2-bedrooms/`, price filters — to narrow results and reduce page counts.
- **Stuck on page 1?** The defaults already hunt hard (`AUTO`, `firefox144`, double rotation for page 1). For extra odds, raise `maxProxyRotations`, tick `browserSeed`, or switch `proxyCountry`. A fresh pool (or a retry later) helps when an IP was flagged at WAF level.
- **Verify your browser can help:** run once with `browserSelfTest` **on** — if it reports "Access Denied", the block is IP-level and the browser won't help either.
- **Custom proxies:** paste your own residential URLs into `proxyUrls` to skip the Apify pool entirely.
- **Keep delays low** — rotation is cheap; leave `browserSeed` off unless page 1 really needs it.

### Related Actors

- [Zillow Scraper](https://apify.com/maxcopell/zillow-scraper) — for-sale and rental listings from Zillow, no daily call limits
- [Redfin Search Scraper](https://apify.com/tri_angle/redfin-search) — real estate properties from Redfin searches
- [Realtor.com Scraper](https://apify.com/solidcode/realtorcom-scraper) — for-sale, for-rent and sold property listings
- [Rent.com Scraper](https://apify.com/memo23/rent-com-scraper) — rental properties, deals, and contact info
- [US Real Estate Multi-Source](https://apify.com/jonn/us-realestate-multisource) — Zillow, Realtor & Redfin in one deduplicated run

### FAQ

#### Why use this actor instead of the official Apartments.com API?

There is **no public Apartments.com API**. CoStar's customer API is limited to authenticated property managers (mostly review retrieval and management of your own listings) and requires OAuth credentials a data buyer can't get. This actor reads public listing data directly — no key, no registration, no contract.

#### What are alternatives to Apartments.com rental data?

Other US rental and real-estate sources available on Apify: [Zillow](https://apify.com/maxcopell/zillow-scraper), [Redfin](https://apify.com/tri_angle/redfin-search), [Realtor.com](https://apify.com/solidcode/realtorcom-scraper), and [Rent.com](https://apify.com/memo23/rent-com-scraper).

#### How do I get rent comps for a city?

Run the actor by city or ZIP with a healthy `maxItems`, then compare asking rents by beds/baths/sqft across listings. Filtered URLs (e.g. `/2-bedrooms/`) narrow results to the exact unit type you're benchmarking. Re-run weekly to track changes.

#### Is scraping Apartments.com legal?

Scraping publicly available rental listings for personal or market analysis is generally acceptable, but you are responsible for complying with Apartments.com's Terms of Service and applicable law. This actor is not affiliated with or endorsed by Apartments.com or CoStar Group, Inc.

#### Why does page 1 sometimes fail?

Apartments.com's Akamai protection is stricter on the first request from a fresh IP. The actor hunts page 1 with a doubled IP rotation and can fall back to a real browser (`browserSeed`), but when the WAF denies the IP itself ("Access Denied"), the retry must come from a different IP or pool. Re-running usually clears it.

#### Can I scrape Apartments.com without a proxy?

The actor needs proxy access — the Apify proxy pool (default) or your own `proxyUrls`. US residential IPs clear Apartments.com best.

### For AI Agents & LLM Apps

This actor is callable via the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) and the Apify REST API.

- **Purpose:** returns structured US rental listings — property name, address, rent prices, beds/baths, square footage, contact phone — from Apartments.com search results.
- **Minimal working input:**

```json
{ "search": "charlotte nc", "maxItems": 10 }
```

- **Variant modes:**
  - Search URL mode: `{ "startUrls": [{ "url": "https://www.apartments.com/charlotte-nc/" }], "maxItems": 10 }`
  - Hard-block fallback: add `"browserSeed": true` only if page 1 keeps getting blocked.
- **Output fields:** `listingId`, `url`, `propertyName`, `address`, `street`, `city`, `state`, `zip`, `latitude`, `longitude`, `rentMin`, `rentMax`, `rentText`, `beds`, `baths`, `sqft`, `contactPhone`, `page`, `searchUrl`, `scrapedAt`.
- **Behaviors an agent should know:**
  - If both `search` and `startUrls` are set, `startUrls` take priority.
  - `maxItems` defaults to 50 if left unset — this caps both results and charges.
  - Free-tier accounts are limited to 10 items per run.
  - One of `search` / `startUrls` is required; a run with neither fails.
  - `browserSeed` / `browserSelfTest` add ~1024 MB memory and ~15 s to the run.
- **Billing:** pay-per-result — **$0.001 per listing** returned + **$0.00005** run start.

### Legal & Compliance Disclaimer

This actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by** Apartments.com or CoStar Group, Inc. "Apartments.com" is a registered trademark of CoStar Group, Inc.

The actor only accesses **publicly available pages** — it does not bypass logins and does not solve CAPTCHAs. Akamai bot challenges are handled by rotating to clean proxy IPs, not by breaking security controls. Users are responsible for complying with Apartments.com's Terms of Service and applicable law when using extracted data.

### SEO Keywords

apartments.com scraper, apartments.com api alternative, us rental listings data, rental market research, rent comps, rent price monitoring, apartment price tracking, rental property database, property management lead generation, leasing office phone list, apartments for rent data, apartment listing scraper, rental data without api key, multifamily housing data, rent comparison data, apartment inventory scraper, us rental data, apartment market analysis, rental analytics dataset, apartment hunting data, relocation apartment data, rental market trends

# Actor input Schema

## `startUrls` (type: `array`):

Apartments.com search result pages (e.g. https://www.apartments.com/charlotte-nc/) or individual listing pages (e.g. https://www.apartments.com/the-artisan-charlotte-nc/pe3k5kr/). You can paste filtered search URLs from the site — all filters are carried through.

## `search` (type: `string`):

Alternative to startUrls — a city, state or ZIP to search, e.g. 'charlotte nc', 'brooklyn ny' or '10001'. Builds the search URL automatically.

## `maxItems` (type: `integer`):

Maximum number of listings to return per run. Search pages are fetched automatically (~40 listings per page, fetched in parallel) until this budget is reached. Apartments.com caps a single search at ~720 listings (18 pages).

## `proxyConfiguration` (type: `object`):

Apartments.com is protected by Akamai Bot Manager. The scraper rotates fresh IPs automatically when a session is flagged. Use the 'Apify proxy pool' selector below to switch pools (RESIDENTIAL recommended).

## `maxProxyRotations` (type: `integer`):

How many fresh proxy sessions to try per request when Akamai returns a block shell. Each session is retried on the same IP first. Page 1 gets double this budget since it faces the worst WAF pressure. Higher = better odds of finding a clean IP, but slower and uses more proxy bandwidth. Default 8.

## `maxConcurrentRotations` (type: `integer`):

How many fresh proxy IPs to try IN PARALLEL per batch when a page is blocked. Each session is a distinct IP, so parallelism just collapses the anti-bot wait time — it is the single biggest speed lever. Lower = gentler on the pool (helps if Akamai throttles fast bursts); higher = faster recovery on blocked pages. Default 4.

## `browser` (type: `string`):

TLS/browser fingerprint used to impersonate a real browser via impit. Akamai vendors the pool per fingerprint; 'firefox' (Firefox 144 TLS) tends to clear Apartments.com better than Chrome on residential proxies. Options: firefox, firefox144, chrome, chrome142, or any impit browser identifier.

## `proxyGroup` (type: `string`):

Which Apify proxy pool to use. AUTO = let Apify pick the best (most reliable for pages 1). RESIDENTIAL also works but some residential IPs are flagged by Akamai. DATACENTER is not available on all plans.

## `proxyCountry` (type: `string`):

Apify proxy country to pin. Apartments.com cards pass more often on US residential IPs, so the default is 'US'. Leave empty to use the proxy pool's default rotation.

## `proxyUrls` (type: `array`):

Optional. Paste your own residential proxy URLs to use INSTEAD of the Apify proxy — useful to test a different proxy pool (e.g. Bright Data, Oxylabs, IPRoyal). Format per entry: http://user:pass@host:port. One URL = one sticky IP; multiple URLs rotate. Leave empty to use the Apify proxy above.

## `browserSeed` (type: `boolean`):

If page 1 stays blocked after the HTTP IP hunt, load it with a real Playwright/Firefox browser to mint a trusted session (cookies + IP), then reuse that session over cheap HTTP for pages 2+. NOTE: it only helps when the block is a TLS/fingerprint block — it cannot bypass Akamai WAF 'Access Denied' IP-level blocks. Adds ~15s and 1024 MB for the first page. OFF by default to keep costs low.

## `browserSelfTest` (type: `boolean`):

DEBUG TOOL — launches a real Playwright/Firefox browser against the first URL and exits. Confirms whether the browser can get through Akamai on your current proxy IP. Useful when page 1 keeps getting blocked. Leaves no data in the dataset.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.apartments.com/charlotte-nc/"
    }
  ],
  "search": "charlotte nc",
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxProxyRotations": 8,
  "maxConcurrentRotations": 4,
  "browser": "firefox144",
  "proxyGroup": "AUTO",
  "proxyCountry": "US",
  "proxyUrls": [
    "http://username:password@proxy.example.com:10000"
  ],
  "browserSeed": false,
  "browserSelfTest": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.apartments.com/charlotte-nc/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/apartments-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrls": [{ "url": "https://www.apartments.com/charlotte-nc/" }] }

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/apartments-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.apartments.com/charlotte-nc/"
    }
  ]
}' |
apify call ahmed_jasarevic/apartments-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/apartments-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/UX7M73A05l8a6eCkx/builds/qryE19tzobLVxwjaz/openapi.json
