# StreetEasy Scraper (Cheap) (`data_api/streeteasy-scraper-cheap`) Actor

StreetEasy scraper that collects NYC rental and sale listings with filters for price, bedrooms, building type, neighborhood, and status, returning one clean row per property.

- **URL**: https://apify.com/data\_api/streeteasy-scraper-cheap.md
- **Developed by:** [Data API](https://apify.com/data_api) (community)
- **Categories:** Real estate, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 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/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

## StreetEasy Listings Scraper

![StreetEasy Listings Scraper](cover.jpg)

Browsing StreetEasy by hand is fine for finding one apartment. It falls apart the moment you need a few hundred listings in a spreadsheet. The site paginates, hides numbers behind cards, and gives you nothing to export. This scraper does the clicking for you: hand it a StreetEasy search URL or a neighborhood slug, and it walks the results page by page and hands back every rental and sale listing as a clean row, with address, price, bedrooms, square footage, status, and coordinates all in their own columns.

### What you get

Each listing comes back as one row with the same shape every time, so columns line up when you load the data into a sheet or database. The fields cover four things:

- **Where it is** — `streetAddress`, `unitLabel`, `neighborhoodName`, `postalCode`, `stateCode`, and `coordinates` for mapping
- **What it costs** — `listPrice`, `effectiveRent`, `priceChangeDelta`, `freeMonths`, and `leaseMonths`
- **What it is** — `bedrooms`, `fullBaths`, `halfBaths`, `squareFeet`, `propertyClass`, `isFurnished`, `newConstruction`, and `availableDate`
- **The listing itself** — `listingRef`, `listingStatus`, `listingSource`, `listedBy`, `photoList`, `has3dTour`, `hasVideo`, `nextOpenHouse`, and the `listingPath` back to StreetEasy

### Quick start

1. Click **Try for free** to open the input form.
2. Either paste a StreetEasy search link into **Search page URL**, or set an **Area slug** like `brooklyn` and tune the filters (price, bedrooms, property kind).
3. Set a **Results cap** to control how many listings you pull, and pick a proxy.
4. Hit **Start**, then download the rows as JSON, CSV, Excel, or XML once the run wraps up.

![How it works](how-it-works.jpg)

### Use cases

- **Rental market tracking** — watch asking rents and net effective rents shift across a neighborhood week over week
- **Buy-side research** — pull every sale listing in a borough and sort by price per square foot
- **Lead lists for brokers** — find by-owner rentals or new developments the moment they post
- **Investment screening** — combine `listPrice`, `squareFeet`, and `coordinates` to rank deals across NYC
- **Relocation planning** — gather furnished units with a given move-in date in one pass
- **Data enrichment** — attach addresses and coordinates to listings you already track elsewhere

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `searchPageUrl` | string | One of `searchPageUrl` or `areaSlug` | A ready-made StreetEasy search link. When set, every filter below is ignored. Example `https://streeteasy.com/for-rent/brooklyn/price:1500-3500\|beds:1-2`. |
| `dealType` | string | No | Collect rentals or homes for sale: `for-rent` or `for-sale`. Default `for-rent`. |
| `areaSlug` | string | One of `searchPageUrl` or `areaSlug` | Neighborhood or borough slug to search, such as `brooklyn` or `soho`. Default `nyc`. |
| `postalCode` | string | No | Limit results to one NYC ZIP, e.g. `11211`. |
| `priceFloor` | integer | No | Smallest price in USD to include. |
| `priceCeiling` | integer | No | Largest price in USD to include. |
| `bedroomsMin` | string | No | Lowest bedroom count to match; `0` means studio. |
| `bedroomsMax` | string | No | Highest bedroom count to match; leave on Any for no upper limit. |
| `bathroomsMin` | string | No | Lowest bathroom count to match. |
| `propertyKinds` | array of strings | No | Building codes to keep: R rental, X house, D1 condo, M multifamily, P1 co-op. |
| `petFriendlyOnly` | boolean | No | Keep only pet-friendly listings. Default `false`. |
| `listingState` | string | No | Market state filter: active, rented, listed, closed, or pending. Default `active`. |
| `ownerListedOnly` | boolean | No | Keep only by-owner rentals with no broker fee. Affects for-rent only. Default `false`. |
| `orderBy` | string | No | Sort order for results. Default `se_score` (Recommended). |
| `resultsLimit` | integer | No | How many listings to gather before stopping. Default `50`; ceiling is 1,400. |
| `proxyConfiguration` | object | No | Proxies for requests. Apify proxy is on by default; switch to Residential if requests get blocked. |

#### Example input

```json
{
    "searchPageUrl": "https://streeteasy.com/for-rent/brooklyn/price:1500-3500|beds:1-2?sort_by=listed_desc",
    "dealType": "for-rent",
    "areaSlug": "brooklyn",
    "postalCode": "11211",
    "priceFloor": 1500,
    "priceCeiling": 4500,
    "bedroomsMin": "1",
    "bedroomsMax": "2",
    "propertyKinds": ["D1", "P1"],
    "petFriendlyOnly": true,
    "listingState": "active",
    "orderBy": "listed_desc",
    "resultsLimit": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
}
```

### Output

Each listing becomes one row. Values that StreetEasy does not publish for a given listing come back as `null`, so the dataset stays rectangular and predictable.

#### Example output

```json
{
    "listingRef": "4239871",
    "neighborhoodName": "Williamsburg",
    "availableDate": "2026-08-01",
    "bedrooms": 2,
    "propertyClass": "RENTAL",
    "fullBaths": 1,
    "isFurnished": false,
    "coordinates": { "latitude": 40.7128, "longitude": -73.9571 },
    "halfBaths": 0,
    "has3dTour": true,
    "hasVideo": false,
    "priceChangeDelta": null,
    "newConstruction": false,
    "leaseMonths": 12,
    "squareFeet": 780,
    "freeMonths": 1,
    "effectiveRent": 3208.33,
    "offMarketDate": null,
    "photoList": [
        { "url": "https://photos.zillowstatic.com/fp/example1.jpg", "key": "example1", "description": "Living room" }
    ],
    "listPrice": 3500,
    "relloExpressFlag": null,
    "listingSlug": "2-bedroom-apartments-williamsburg",
    "listedBy": "Prime Brooklyn Realty",
    "listingSource": "PARTNER",
    "stateCode": "NY",
    "listingStatus": "ACTIVE",
    "streetAddress": "215 North 8th Street",
    "nextOpenHouse": null,
    "unitLabel": "#4B",
    "listingPath": "/building/215-north-8th-street-brooklyn/4b",
    "postalCode": "11211",
    "listingTier": null,
    "unitId": "#4B"
}
```

#### Output fields

| Field | Type | Description |
|-------|------|-------------|
| `listingRef` | string | StreetEasy's own listing identifier |
| `neighborhoodName` | string | Neighborhood or area name |
| `availableDate` | string | Move-in date as YYYY-MM-DD |
| `bedrooms` | integer | Bedroom count, where 0 is a studio |
| `propertyClass` | string | Building category such as RENTAL, CONDO, or COOP |
| `fullBaths` | integer | Number of full bathrooms |
| `isFurnished` | boolean | True when the unit comes furnished |
| `coordinates` | object | Map location with latitude and longitude |
| `halfBaths` | integer | Number of half bathrooms |
| `has3dTour` | boolean | True when a 3D walkthrough is attached |
| `hasVideo` | boolean | True when the listing has video |
| `priceChangeDelta` | number | Flagged price movement, or null |
| `newConstruction` | boolean | True for a new development |
| `leaseMonths` | integer | Lease length in months, or null |
| `squareFeet` | integer | Indoor living area in square feet |
| `freeMonths` | integer | Free rent months offered, or null |
| `effectiveRent` | number | Monthly rent after concessions are spread out |
| `offMarketDate` | string | Date the listing left the market, or null |
| `photoList` | array | Photo objects, each with url, key, and description |
| `listPrice` | integer | Sale price or monthly rent in USD |
| `relloExpressFlag` | string | Rello Express marker, or null |
| `listingSlug` | string | URL-friendly slug, or null |
| `listedBy` | string | Listing broker or management company |
| `listingSource` | string | Origin of the listing, e.g. PARTNER or OWNER |
| `stateCode` | string | Two-letter state code, e.g. NY |
| `listingStatus` | string | Current status, e.g. ACTIVE, RENTED, PENDING |
| `streetAddress` | string | Street address of the property |
| `nextOpenHouse` | object | Upcoming open house details, or null |
| `unitLabel` | string | Unit number as shown, e.g. #4B |
| `listingPath` | string | Relative path to the listing on StreetEasy |
| `postalCode` | string | Five-digit ZIP code |
| `listingTier` | string | Tier classification, or null |
| `unitId` | string | Internal unit identifier, e.g. #4B |

Rows that record a fetch failure carry `isError`, `errorMessage`, and `pageNumber` instead of listing fields.

### Tips for best results

- **Test with a small cap first.** Set `resultsLimit` to 20–30 and confirm the columns match your pipeline before pulling the full set.
- **A search URL beats filters for exact matches.** If you already have the search dialed in on StreetEasy, paste the link into `searchPageUrl` and skip the filter fields.
- **Switch to Residential proxies if results thin out.** StreetEasy can rate-limit datacenter IPs; residential clears most blocks.
- **Remember `bedrooms` 0 means studio.** Set `bedroomsMin` and `bedroomsMax` to `0` to pull studios only.
- **`ownerListedOnly` works on rentals.** Combine it with `dealType` set to `for-rent` to surface no-fee listings.
- **Lease incentives live in their own fields.** Compare `listPrice` against `effectiveRent` and `freeMonths` to see the real cost of a rental.

### How can I use StreetEasy listing data?

**How can I use the StreetEasy Listings Scraper to track NYC rent prices?**
Set an `areaSlug` like `brooklyn`, choose `for-rent`, and run the scraper on a schedule. Each run returns `listPrice`, `effectiveRent`, and `freeMonths` for every active listing, so you can chart asking rents by neighborhood over time and catch the moment concessions start creeping in.

**How can I export StreetEasy sale listings to a spreadsheet?**
Switch `dealType` to `for-sale`, set your `priceFloor` and `priceCeiling`, and start the run. Every listing comes back as a row with `listPrice`, `squareFeet`, `bedrooms`, and `streetAddress`, ready to download as CSV or Excel and sort by price per square foot.

**How can I scrape StreetEasy listings for a single ZIP code?**
Fill in `postalCode` (for example `11211`) along with the area, and the scraper limits results to that ZIP. Pair it with `propertyKinds` to keep only condos or co-ops, then map the rows using the `coordinates` field.

**How can I find no-fee or by-owner rentals on StreetEasy?**
Turn on `ownerListedOnly` with `dealType` set to `for-rent`. The scraper returns only rentals posted directly by owners with no broker fee, each row carrying the address, price, bedroom count, and a link back to the listing.

### Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses or private contact information. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### Support

Questions, feature requests, or a field you'd like added? Reach out at <data.apify@proton.me> and we'll get back to you.

# Actor input Schema

## `searchPageUrl` (type: `string`):

Drop in a ready-made StreetEasy search link and the scraper runs it as-is. Fill this and every filter below is skipped. You can leave it blank and build a search with the filters instead.

## `dealType` (type: `string`):

Choose whether to collect rentals or homes listed for sale.

## `areaSlug` (type: `string`):

The neighborhood or borough slug to look in. Used when no Search page URL is set. Try values like nyc, brooklyn, manhattan, bronx, queens, soho, harlem, astoria, williamsburg, upper-east-side, park-slope, or crown-heights.

## `postalCode` (type: `string`):

Restrict results to one NYC ZIP, such as 10001 or 11238. Skip it to cover the whole area.

## `priceFloor` (type: `integer`):

Smallest price in US dollars to include. Skip for no lower bound.

## `priceCeiling` (type: `integer`):

Largest price in US dollars to include. Skip for no upper bound.

## `bedroomsMin` (type: `string`):

Lowest bedroom count to match. A studio counts as 0.

## `bedroomsMax` (type: `string`):

Highest bedroom count to match. A studio counts as 0. Keep on Any to leave the top end open.

## `bathroomsMin` (type: `string`):

Lowest bathroom count to match.

## `propertyKinds` (type: `array`):

Limit results by building category. Add one code per line: R = Rental building, X = House, D1 = Condo, M = Multifamily, P1 = Co-op. Skip it to keep every kind.

## `petFriendlyOnly` (type: `boolean`):

Turn on to keep only listings that welcome pets.

## `listingState` (type: `string`):

Restrict to listings in a given state of the market.

## `ownerListedOnly` (type: `boolean`):

Turn on to keep only rentals posted by the owner with no broker fee. Has effect on for-rent searches only.

## `orderBy` (type: `string`):

How the listings should be sorted.

## `resultsLimit` (type: `integer`):

How many listings to gather before stopping. The ceiling is 1,400.

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

Pick the proxies to route requests through. Helps you dodge IP blocks and rate limiting.

## Actor input object example

```json
{
  "searchPageUrl": "https://streeteasy.com/for-rent/brooklyn/price:1500-3500|beds:1-2?sort_by=listed_desc",
  "dealType": "for-rent",
  "areaSlug": "williamsburg",
  "postalCode": "11211",
  "priceFloor": 1500,
  "priceCeiling": 4500,
  "bedroomsMin": "",
  "bedroomsMax": "",
  "bathroomsMin": "",
  "propertyKinds": [
    "D1",
    "P1"
  ],
  "petFriendlyOnly": false,
  "listingState": "active",
  "ownerListedOnly": false,
  "orderBy": "se_score",
  "resultsLimit": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "areaSlug": "brooklyn",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("data_api/streeteasy-scraper-cheap").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 = {
    "areaSlug": "brooklyn",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("data_api/streeteasy-scraper-cheap").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 '{
  "areaSlug": "brooklyn",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call data_api/streeteasy-scraper-cheap --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=data_api/streeteasy-scraper-cheap",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/EmkJGGjb1quo24DV4/builds/eKhqPeBm9f4OZJpCX/openapi.json
