# Zumper Rental Listings Scraper (`automation-lab/zumper-rental-listings-scraper`) Actor

Scrape public Zumper rentals by city, US ZIP code, or search URL with prices, beds, baths, amenities, photos, building details, contacts, ratings, availability, and timestamps.

- **URL**: https://apify.com/automation-lab/zumper-rental-listings-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Zumper Rental Listings Scraper

Collect structured public rental inventory from Zumper by city, US ZIP code, or a Zumper search URL.

The Actor returns one dataset row per unique listing with rent ranges, bedrooms, bathrooms, address, coordinates, amenities, photos, building details, public agent or brokerage contact fields, ratings, availability, and source timestamps.

It uses Zumper's structured listing response rather than rendering every page in a browser. That keeps runs lightweight and makes recurring market monitoring practical.

### What can you do with this Zumper scraper?

- Monitor rental inventory and asking-rent changes in a city.
- Build ZIP-level datasets for local market analysis.
- Compare advertised rent ranges across several US markets.
- Find public property-manager, agent, and brokerage contact details attached to listings.
- Track availability, amenities, pet-policy codes, and listing timestamps.
- Feed rental data into spreadsheets, databases, dashboards, or alerts.

The Actor is designed for public search results. It does not log in, message agents, submit forms, or scrape private account data.

### Who is it for?

**Rental-market analysts** can schedule the same searches and compare inventory, price ranges, and listing turnover over time.

**Property managers and operators** can monitor competing buildings, advertised amenities, and available floorplans in a local market.

**Real-estate investors** can collect comparable asking rents for early-stage market research and underwriting support.

**Lead and data teams** can export public listing contacts and building details into an authorized enrichment workflow.

**Developers** can use the API, webhooks, Make, Zapier, or MCP to connect structured Zumper data to another application.

### Why use this Actor?

- **Three useful input routes:** city/state, five-digit US ZIP code, and full Zumper search URL.
- **Real pagination:** `maxItems` can go beyond the first 10 listings.
- **Stable deduplication:** repeated listings are deduplicated by Zumper listing ID across all searches in one run.
- **Rich records:** list data already includes prices, beds, baths, photos, amenities, building, rating, and contacts.
- **Lightweight runs:** the current implementation uses direct JSON requests and 256 MB of memory.
- **Fail-closed behavior:** malformed URLs and invalid limits stop the run instead of returning misleading empty output.

No scraper can guarantee that every Zumper record has every field. Missing source values are returned as `null` or an empty array.

### What data does it extract?

| Group | Fields |
| --- | --- |
| Identity | `listingId`, `url`, `sourceSearchUrl`, `title` |
| Location | `address`, `city`, `state`, `zipCode`, `latitude`, `longitude` |
| Pricing | `minRent`, `maxRent`, `previousRent` |
| Layout | `minBedrooms`, `maxBedrooms`, `minBathrooms`, `maxBathrooms` |
| Property | `propertyType`, `propertyTypeCode`, `listingTypeCode`, `listingStatusCode` |
| Availability | `availableDate`, `leaseTypeCode`, `minLeaseDays`, `maxLeaseDays` |
| Features | `amenities`, `buildingAmenities`, `petPolicyCodes`, `photoUrls` |
| Building | `building.id`, `building.name` |
| Contact | agent and brokerage IDs/names, public phone number |
| Quality and text | `rating`, `description`, `isMessageable` |
| Time | `createdAt`, `listedAt`, `modifiedAt`, `scrapedAt` |

Source enum values such as property, lease, pet, and status codes are preserved as numeric codes. `propertyType` is inferred only when the canonical URL clearly identifies the property route.

### Getting started

1. Open the Actor in Apify Console.
2. Keep the prefilled `Austin, TX` location or replace it with your market.
3. Set `maxItems` to the maximum number of unique listings you want.
4. Click **Start**.
5. Open the **Dataset items** output when the run finishes.
6. Export the results as JSON, CSV, Excel, XML, or another supported dataset format.

The prefilled input is deliberately small enough for a first test while still demonstrating pagination.

### Input parameters

#### `locations`

An array of location strings.

Supported forms:

- city plus state abbreviation, such as `Austin, TX`;
- another canonical market label, such as `Denver, CO`;
- a five-digit US ZIP code, such as `10001`.

ZIP inputs are resolved to a city/state market and then constrained to the requested postal code. ZIP lookup currently supports the United States only.

#### `searchUrls`

An array of full public URLs beginning with:

```text
https://www.zumper.com/apartments-for-rent/
```

Use this mode when you already configured a search on Zumper. Existing URL filters are preserved. If the URL includes `page`, that page becomes the starting page.

Non-Zumper hosts and non-search Zumper URLs are rejected.

#### `maxItems`

The maximum number of unique records saved across all locations and URLs.

- Default: `100`
- Minimum: `1`
- Maximum: `10000`

The Actor stops scheduling new pages when it reaches this limit. If fewer matching listings exist, it ends normally with the available results.

### Example inputs

#### Search one city

```json
{
  "locations": ["Austin, TX"],
  "maxItems": 100
}
```

#### Search one US ZIP code

```json
{
  "locations": ["10001"],
  "maxItems": 50
}
```

#### Use a Zumper search URL

```json
{
  "searchUrls": [
    "https://www.zumper.com/apartments-for-rent/new-york-ny/10001"
  ],
  "maxItems": 100
}
```

#### Monitor multiple markets

```json
{
  "locations": ["Austin, TX", "Denver, CO", "Seattle, WA"],
  "maxItems": 500
}
```

You can combine `locations` and `searchUrls`. Identical targets and repeated listing IDs are removed within the run.

### Output example

The default dataset contains the primary listing records. A representative record looks like this:

```json
{
  "listingId": 12345678,
  "url": "https://www.zumper.com/apartment-buildings/p123456/sample-residences-austin-tx",
  "sourceSearchUrl": "https://www.zumper.com/apartments-for-rent/austin-tx",
  "title": "A2",
  "address": "100 Sample Avenue",
  "city": "Austin",
  "state": "TX",
  "zipCode": "78701",
  "latitude": 30.2672,
  "longitude": -97.7431,
  "minRent": 1650,
  "maxRent": 2450,
  "minBedrooms": 1,
  "maxBedrooms": 2,
  "minBathrooms": 1,
  "maxBathrooms": 2,
  "propertyType": "apartment building",
  "amenities": ["Stainless Steel Appliances", "Balcony"],
  "buildingAmenities": ["Fitness Center", "Resident Lounge"],
  "petPolicyCodes": [1, 2],
  "photoUrls": ["https://img.zumpercdn.com/123456789/1280x960"],
  "building": {
    "id": 123456,
    "name": "Sample Residences"
  },
  "agent": {
    "id": 654321,
    "name": "Sample Property Team",
    "brokerageId": 98765,
    "brokerageName": "Sample Realty",
    "phone": "(512) 555-0100"
  },
  "rating": 8.7,
  "createdAt": "2026-07-01T12:00:00.000Z",
  "listedAt": "2026-07-02T12:00:00.000Z",
  "modifiedAt": "2026-07-15T12:00:00.000Z",
  "scrapedAt": "2026-07-27T12:00:00.000Z"
}
```

Fields may be `null` when Zumper does not publish a value. Amenity, photo, and pet-policy fields are arrays and may be empty.

### How much does it cost to scrape Zumper rental listings?

This Actor uses pay-per-event pricing:

- **Start:** $0.005 once per valid run.
- **Listing:** $0.000041071 per saved listing at the FREE tier.
- Higher platform tiers receive lower per-listing prices, down to $0.00001 at DIAMOND.

At the FREE tier, examples before any platform-level free usage or credits are:

| Saved listings | FREE-tier calculation | Approximate charge |
| ---: | --- | ---: |
| 10 | $0.005 + 10 × $0.000041071 | about half a cent |
| 100 | $0.005 + 100 × $0.000041071 | under one cent |
| 1,000 | $0.005 + 1,000 × $0.000041071 | under five cents |

Only normalized, unique listing rows are charged as listing events. Duplicate, rejected, empty, and failed records are not charged as listing events.

Apify may separately charge for platform compute according to your plan. This lightweight HTTP Actor does not expose a residential proxy or browser mode in the current version.

### Pagination, limits, and deduplication

Zumper returns search data in pages. The Actor requests pages sequentially and stops when:

- `maxItems` is reached;
- the source returns an empty page;
- a partial final page indicates exhaustion; or
- the reported matching count has been consumed.

Deduplication uses the stable numeric `listingId`. When two input searches overlap, the first occurrence is saved and later occurrences are skipped.

`sourceSearchUrl` records the exact search page that produced each saved item, which helps with auditing and debugging.

### Recurring rental-market monitoring

For recurring analysis:

1. Create one Actor task with stable market inputs.
2. Schedule it daily or weekly in Apify Console.
3. Send completion data through a webhook or integration.
4. Store snapshots in your warehouse or spreadsheet.
5. Compare by `listingId`, `minRent`, `maxRent`, `listedAt`, and `modifiedAt`.

Each Actor run has a separate default dataset. The Actor does not silently merge old records into a new run.

### Integrations

Common patterns include:

- **Google Sheets:** append current inventory for a weekly market report.
- **Make or Zapier:** trigger alerts when downstream logic detects a new listing or rent change.
- **Webhooks:** notify a data pipeline when a scheduled run finishes.
- **BigQuery or Snowflake:** retain snapshots for longitudinal analysis.
- **Python or JavaScript:** call the Actor and process the default dataset programmatically.
- **MCP:** let an AI assistant run a bounded search and inspect structured listing output.

Use public contact fields responsibly. Do not use the Actor for unsolicited spam or discriminatory housing practices.

### Run with the Apify API

Set `APIFY_TOKEN` in your environment. Do not hard-code tokens in source control.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~zumper-rental-listings-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"locations":["Austin, TX"],"maxItems":100}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/zumper-rental-listings-scraper').call({
  locations: ['Austin, TX'],
  maxItems: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/zumper-rental-listings-scraper').call(run_input={
    'locations': ['10001'],
    'maxItems': 50,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

For asynchronous workflows, start a run without waiting and poll the run endpoint or attach a webhook.

### Use with Apify MCP

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/zumper-rental-listings-scraper"
```

#### Claude Desktop

Add this JSON to Claude Desktop's MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/zumper-rental-listings-scraper"
    }
  }
}
```

#### Cursor

Add the same `mcpServers.apify.url` entry to your Cursor MCP configuration, then reload the MCP tools.

#### VS Code

Add the same HTTP MCP server URL to your VS Code MCP configuration and enable the Apify server for the workspace.

Example prompts:

- “Run the Zumper Rental Listings Scraper for Austin, TX with a limit of 25 and summarize the rent range.”
- “Collect 50 listings in ZIP 10001 and group them by bedroom range.”
- “Compare the advertised minimum rents from Austin and Denver.”

Always review AI-generated analysis and the source records before making a housing or investment decision.

### Reliability and error behavior

Requests use a 30-second timeout and bounded retries for transient network errors, HTTP 429 responses, and temporary server errors.

The Actor does not repeatedly retry deterministic malformed requests. It validates the response content type and requires a recognizable `listables` array. A challenge page or unexpected HTML is treated as an error, not as a valid empty market.

The current route needs no login, browser, or proxy. If Zumper changes its public response shape or access controls, a run may fail until the Actor is updated.

### Limitations

- Search coverage is limited to public listings returned by Zumper for the supplied market or URL.
- City strings should include a state abbreviation to avoid ambiguous market slugs.
- ZIP-only resolution currently supports five-digit US ZIP codes.
- Source numeric codes are preserved because Zumper can change undocumented enum meanings.
- Some records represent a building or floorplan range rather than one individual unit.
- Contact details, descriptions, ratings, availability, and timestamps are not present on every listing.
- Results can change between pages while a live marketplace updates.
- This version does not fetch a separate detail page for every listing.
- The Actor does not bypass account gates or CAPTCHAs.

### Responsible use and legality

Zumper data can include public business contact details and housing information. Use it only for lawful purposes and only where you are authorized to process the data.

You are responsible for reviewing Zumper's terms, applicable database rights, privacy rules, fair-housing law, telemarketing rules, and your downstream retention policies. Avoid collecting more personal data than your workflow needs.

Do not use the output to discriminate against protected classes, harass contacts, send unsolicited bulk messages, or make automated eligibility decisions without appropriate legal review.

This Actor is an independent data-extraction tool and is not affiliated with or endorsed by Zumper.

### Troubleshooting

#### The run returns zero items

Confirm that the city/state or URL currently has public matching rentals. Try the same market in Zumper's public search. A valid no-result search finishes successfully with zero dataset rows.

#### My city returns the wrong market

Include the two-letter state abbreviation, for example `Portland, OR` rather than only `Portland`.

#### A ZIP code fails

Use a five-digit US ZIP code. Canadian postal codes and non-US postal codes are not supported by ZIP-only input in this version. You can use a valid Zumper search URL instead.

#### The run fails on a Zumper URL

Use a full public URL under `https://www.zumper.com/apartments-for-rent/`. Listing-detail and apartment-building URLs are outputs, not search inputs.

#### I received fewer rows than `maxItems`

`maxItems` is a cap, not a promised count. The market may have fewer public listings, overlapping searches may deduplicate records, or Zumper may return fewer rows.

#### Where are the results?

Open the run's **Output** tab and follow **Dataset items**. API users can read `defaultDatasetId` from the run object.

### Related Automation Labs Actors

- [Zillow Scraper](https://apify.com/automation-lab/zillow-scraper) for another US property marketplace.
- [Realtor.com Scraper](https://apify.com/automation-lab/realtor-scraper) for US property listing research.
- [HousingAnywhere Rental Listings Scraper](https://apify.com/automation-lab/housinganywhere-rental-listings-scraper) for international medium- and long-term rentals.

Use separate Actors when you need source-specific fields. Join datasets downstream by normalized address or coordinates only after accounting for source differences.

### FAQ

#### Does it require a Zumper account?

No. The current version uses public rental-search data and does not log in.

#### Does it use a browser or residential proxy?

No. The current implementation is HTTP-first and does not expose an automatic browser or proxy fallback.

#### Can it scrape multiple cities in one run?

Yes. Add each city to `locations`; the global `maxItems` applies across all inputs.

#### Can it scrape one listing-detail URL?

No. This Actor's input contract is market/search discovery. It emits listing URLs in the output.

#### Are photo files downloaded into storage?

No. `photoUrls` contains direct public Zumper CDN URLs. The Actor does not download image binaries, saving time and storage.

#### Are results real-time?

They reflect what the public source returned during the run. “Real-time” completeness is not guaranteed because listings can change while pages are being collected.

#### Can I schedule it?

Yes. Save a task and use Apify Schedules for recurring inventory snapshots.

#### How are duplicates handled?

The Actor saves each `listingId` at most once per run, even when input markets overlap.

#### Is every output field always present?

The schema is stable, but source values can be `null` or empty arrays. Check nullability in downstream code.

# Actor input Schema

## `locations` (type: `array`):

Cities with state abbreviations (for example, Austin, TX) or five-digit US ZIP codes. Use separate entries for separate markets.

## `searchUrls` (type: `array`):

Full public zumper.com/apartments-for-rent search URLs. URL filters and an optional starting page are preserved.

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

Maximum number of unique rental listing records saved across all searches.

## Actor input object example

```json
{
  "locations": [
    "Austin, TX"
  ],
  "maxItems": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

Default dataset containing one normalized record per unique Zumper listing.

# 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 = {
    "locations": [
        "Austin, TX"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/zumper-rental-listings-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 = {
    "locations": ["Austin, TX"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/zumper-rental-listings-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "locations": [
    "Austin, TX"
  ],
  "maxItems": 20
}' |
apify call automation-lab/zumper-rental-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/zumper-rental-listings-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/aPiRv13fyJMkOVbAr/builds/74CHEsmLOek5Takk3/openapi.json
