# StreetEasy Scraper — NYC Rentals and Sales (`crawloop/streeteasy-scraper`) Actor

StreetEasy scraper for New York City apartments for rent and for sale. Each row has price, beds, baths, neighborhood, brokerage, and address.

- **URL**: https://apify.com/crawloop/streeteasy-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 listings

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## StreetEasy Scraper — NYC Rentals and Sales

> **Disclaimer:** Unofficial tool — not affiliated with, sponsored by, or endorsed by StreetEasy (Zillow, Inc.) or its affiliates. Data is read from publicly accessible search result pages only. No login. You are responsible for complying with applicable law (including GDPR where personal data appears) and the site’s terms. No warranty on accuracy or availability. Provided for informational and research use.

**StreetEasy scraper** for New York City apartments **for rent** and **for sale** across Manhattan, Brooklyn, Queens, the Bronx, and Staten Island, or one neighborhood such as Williamsburg. Each row has asking price, beds, baths, neighborhood, ZIP, brokerage name, and map coordinates. Use it as a **StreetEasy API alternative** from **Python**, **Node.js**, **cURL**, or **Apify MCP**. Results land in the default dataset as JSON.

**Best for:** rent and sale comps in one borough or neighborhood, and a scheduled check that saves only new listing ids.

| Actor | Role |
| :--- | :--- |
| StreetEasy Scraper ◄── you are here | NYC rent and sale search cards |
| [Realtor.com Scraper](https://apify.com/crawloop/realtor-com-scraper) | US sold comps, ZIP, and listing monitor |
| [LoopNet Scraper](https://apify.com/crawloop/loopnet-scraper) | US commercial sale, lease, and auctions |

### When to use this Actor

- **Borough or neighborhood** — Set an area such as `Brooklyn` or `Upper East Side` and choose rent or sale.
- **A filtered search you already built** — Paste the search URL. Area fields are ignored when Start URLs is set.
- **New-listing monitor** — Schedule the same search. Later runs save listing ids that were not stored last time. A quiet tick writes zero rows.
- **Price and brokerage from the card** — Rent or sale price, beds, and the listing name are taken from the search result. This run does not open each property page.

### When not to use this Actor

- **US homes outside New York** — For sold comps and ZIP searches on a national portal, use [Realtor.com Scraper](https://apify.com/crawloop/realtor-com-scraper).
- **Commercial property** — For sale, lease, and auction cards, use [LoopNet Scraper](https://apify.com/crawloop/loopnet-scraper).
- **Agent emails, phones, or a license database** — Those are not on the search card. This Actor does not log in and does not open detail pages.
- **A full NYC dump in one run** — Cap `maxItems`. Split by borough or neighborhood.

### Key features

- **Search cards** — One page request returns about 14 listings. Default **256 MB**.
- **Rent and sale** — Borough or neighborhood, or a pasted search URL.
- **Price, beds, baths** — Net effective rent and free months when the card states them.
- **Listed by** — Brokerage or listing name shown on the public card.
- **Monitor** — Named key-value store of listing ids already saved for that search.

### Input

| Field | Required | Default | What it does |
| :--- | :--- | :--- | :--- |
| Area | No | Brooklyn | Borough or neighborhood. Ignored when Start URLs is set. |
| Rent or sale | No | For rent | Search type for the area. |
| Start URLs | No | empty | Search URLs. Overrides the fields above. |
| Max listings | No | 25 | Cap across all searches. Maximum 200. |
| Monitor mode | No | off | Save only listing ids not seen on the previous run of this search. |
| Proxy | No | Unblocker, US | Required. Datacenter and residential IPs are denied before the page loads. |

```json
{
  "area": "Brooklyn",
  "transaction": "for-rent",
  "maxItems": 25,
  "monitorMode": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["UNBLOCKER"],
    "apifyProxyCountry": "US"
  }
}
```

A search URL overrides Area and Rent or sale:

```json
{
  "startUrls": [{ "url": "https://streeteasy.com/for-sale/manhattan" }],
  "maxItems": 25,
  "monitorMode": false
}
```

### Output

One dataset row per listing.

| Field | Meaning |
| :--- | :--- |
| `listingId` | Listing path |
| `url` | Listing URL |
| `address`, `street`, `unit` | Address from the card |
| `neighborhood`, `area`, `state`, `zip` | Location |
| `transaction` | `for-rent` or `for-sale` |
| `price`, `priceText`, `currency` | Asking rent or sale price |
| `netEffectiveRent`, `monthsFree` | Concession, when the card states one |
| `beds`, `baths`, `halfBaths`, `sqft` | Size. Studio beds are 0. Sqft only when the card shows a number |
| `furnished`, `newDevelopment`, `buildingType` | Flags from the card |
| `listedBy` | Public card name |
| `openHouseStart`, `openHouseEnd` | Open house when the search page lists one |
| `latitude`, `longitude` | Map point |
| `image` | Primary photo |
| `sourceUrl` | Search page |
| `scrapedAt` | UTC timestamp |

```json
{
  "listingId": "building/fulton-greene/10w",
  "url": "https://streeteasy.com/building/fulton-greene/10w",
  "address": "570 Fulton Street #10W",
  "neighborhood": "Fort Greene",
  "zip": "11217",
  "transaction": "for-rent",
  "price": 4410,
  "currency": "USD",
  "beds": 1,
  "baths": 1,
  "listedBy": "Goose Property Management LLC",
  "newDevelopment": true
}
```

### Use cases

- Pull Brooklyn rentals and compare asking rent, beds, and neighborhood in a spreadsheet.
- Build a brokerage list from the names printed on public search cards.
- Schedule a morning run in monitor mode and export only listing ids that were not in yesterday’s file.
- Feed address, price, and beds into an internal comps sheet. For sold comps outside this portal, continue with [Realtor.com Scraper](https://apify.com/crawloop/realtor-com-scraper).

### Integration examples

Replace `APIFY_TOKEN`. The slug below is the Store name.

#### Node.js

```javascript
import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor("crawloop/streeteasy-scraper").call({
  area: "Brooklyn",
  transaction: "for-rent",
  maxItems: 25,
});
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("crawloop/streeteasy-scraper").call(run_input={
    "area": "Manhattan",
    "transaction": "for-sale",
    "maxItems": 25,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(len(items))
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/crawloop~streeteasy-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"area":"Brooklyn","transaction":"for-rent","maxItems":10}'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp).
Connect your Apify account, then call this Actor by its Store name `crawloop/streeteasy-scraper`.

Example prompts:

- "Run StreetEasy Scraper for Brooklyn for-rent listings and return the top 20 rows as JSON"
- "Scrape StreetEasy sale listings in Manhattan and summarize price, beds, and neighborhood"
- "Run StreetEasy Scraper in monitor mode for Queens rentals, then use Realtor.com Scraper for sold comps"

### Suite next step

This Actor covers NYC rent and sale search cards. For sold comps and ZIP searches on a national portal, run [Realtor.com Scraper](https://apify.com/crawloop/realtor-com-scraper). For commercial sale and lease, run [LoopNet Scraper](https://apify.com/crawloop/loopnet-scraper).

### FAQ

**Does this open every property page?**
No. Rows are the search cards: price, beds, neighborhood, and the name on the card. Phone and email are not on that card.

**Why is a proxy required?**
The search page is denied from datacenter and ordinary residential IPs. The default proxy is Apify Unblocker in the US.

**What does monitor mode skip?**
Listing ids already stored for that same search URL. Change the area or the transaction and it is a new cursor. A run with no new ids writes zero rows.

**Which New York areas work?**
A borough such as Brooklyn, Manhattan, Queens, Bronx, or Staten Island, or a neighborhood such as Upper East Side. A pasted for-rent or for-sale search URL keeps the filters already in that address.

**Can I export rentals and sales?**
Yes. `for-rent` returns asking rent. `for-sale` returns asking sale price. Each saved row is one search card in the JSON dataset.

# Actor input Schema

## `area` (type: `string`):

NYC borough or neighborhood, for example Brooklyn, Manhattan, Queens, or Williamsburg. Ignored when Start URLs is set.

## `transaction` (type: `string`):

Search type used with Area. Ignored when Start URLs is set.

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

StreetEasy search URLs such as a borough or neighborhood results page. When this list is set, Area and Rent or sale are ignored.

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

Maximum listing rows across all searches. One search page is about 14 cards.

## `monitorMode` (type: `boolean`):

Save only listing ids that were not saved for this search on a previous run. A quiet tick writes zero rows.

## `monitorStateStore` (type: `string`):

Named key-value store for listing ids already seen. Used only when monitor mode is on.

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

Apify Unblocker in the United States. Datacenter and residential IPs are denied before the search page loads.

## Actor input object example

```json
{
  "area": "Brooklyn",
  "transaction": "for-rent",
  "maxItems": 25,
  "monitorMode": false,
  "monitorStateStore": "streeteasy-monitor",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

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

Default dataset items — one listing per row.

# 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 = {
    "area": "Brooklyn",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "UNBLOCKER"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/streeteasy-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 = {
    "area": "Brooklyn",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["UNBLOCKER"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/streeteasy-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 '{
  "area": "Brooklyn",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call crawloop/streeteasy-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawloop/streeteasy-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/MupdthZbKWMlrYNiw/builds/0YVO5uJLdyuFC3aa6/openapi.json
