StreetEasy Listing Monitor
Pricing
Pay per event
StreetEasy Listing Monitor
Snapshot and monitor public StreetEasy NYC sale and rental searches with normalized prices, status, days on market, broker, and change metadata.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Stas Persiianenko
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
10 days ago
Last modified
Categories
Share
StreetEasy Listing Monitor turns public NYC sale and rental searches into stable, normalized listing records.
Use it as a StreetEasy scraper for one-time apartment research or schedule repeat runs to identify new, repriced, status-changed, updated, and removed listings.
Each record includes a stable listing ID, current price, source status, source-derived days on market, broker label, property facts, coordinates, and observation metadata.
The Actor supports public borough and all-NYC search URLs for rentals and sales.
It does not require a StreetEasy account.
What does StreetEasy Listing Monitor do?
The Actor accepts one or more public StreetEasy search URLs.
It queries the same structured listing service used by the public site, normalizes sale and rental results, and stores them in the default Apify dataset.
For every accepted listing it also retrieves the source creation timestamp used to calculate daysOnMarket.
With monitoring enabled, the Actor stores a private snapshot under a hash of your stateKey.
Later runs compare the current snapshot with that prior state.
The result is ready for spreadsheets, databases, dashboards, webhooks, and scheduled market-monitoring workflows.
Who is it for?
- Real estate analysts tracking NYC asking-price and inventory movements.
- Buyer agents building current sale comps for a borough.
- Rental teams monitoring new StreetEasy apartments in Brooklyn or Manhattan.
- Investors watching listings for price or status changes.
- Data teams that need consistent records instead of page-specific HTML.
- Developers building a private StreetEasy data pipeline through the Apify API.
This Actor is designed for inventory observation.
It does not contact brokers, submit forms, log in, or collect private account data.
Why use normalized listing snapshots?
StreetEasy pages are useful for browsing, but repeated analysis benefits from stable fields.
The Actor uses listingType + listingId as the comparison identity.
It records both source timestamps and observation timestamps.
That distinction helps answer two different questions:
- When did StreetEasy create or update this listing?
- When did my own workflow first and most recently observe it?
The sourceFingerprint hashes change-relevant fields so downstream systems can deduplicate observations.
Supported StreetEasy search URLs
Use HTTPS search pages for all NYC or one borough.
Supported rental forms include:
https://streeteasy.com/for-rent/nychttps://streeteasy.com/for-rent/manhattanhttps://streeteasy.com/for-rent/brooklynhttps://streeteasy.com/for-rent/queenshttps://streeteasy.com/for-rent/bronxhttps://streeteasy.com/for-rent/staten-island
Replace for-rent with for-sale for sale inventory.
Unsupported hosts, listing detail URLs, building pages, arbitrary neighborhood slugs, and non-HTTPS URLs fail closed with a clear input error.
What StreetEasy data is extracted?
| Field | Meaning |
|---|---|
listingId | Stable StreetEasy listing ID |
listingType | rent or sale |
url | Canonical public listing URL |
street, unit | Source address and unit |
areaName | StreetEasy neighborhood label |
price, currency | Current asking price or monthly rent in USD |
priceDelta | Latest source-reported price change when available |
status | Current source listing status |
listedAt | Source listing creation timestamp |
updatedAt | Latest source update timestamp |
daysOnMarket | Whole days since listedAt |
bedrooms | Bedroom count |
bathrooms, halfBathrooms | Full and half bathroom counts |
livingAreaSquareFeet | Reported living area when available |
buildingType | Source building classification |
brokerName | Brokerage or source-group label |
sourceType | StreetEasy ingestion source classification |
latitude, longitude | Listing coordinates |
sourceSearchUrl | Input URL that produced the record |
sourcePage | One-based result page; zero for removed records |
observedAt | Current run observation timestamp |
firstSeenAt | First observation timestamp for this monitor |
changeType | Comparison classification |
previousPrice, previousStatus | Prior monitor values |
sourceFingerprint | Hash of change-relevant source fields |
Source fields may be null when StreetEasy does not provide a value.
Getting started
- Open the Actor input page.
- Add a supported StreetEasy NYC sale or rental search URL.
- Set
maxItemsto the number of records you need. - Keep
maxPagessmall for an initial run. - Click Start.
- Open the default dataset and select the StreetEasy listings view.
- Export JSON, CSV, Excel, XML, or RSS as needed.
A useful first input is:
{"startUrls": [{ "url": "https://streeteasy.com/for-rent/brooklyn" }],"maxItems": 20,"maxPages": 1}
Input parameters
startUrls
Required array of supported public StreetEasy search URLs.
You can mix sale and rental searches in one run.
maxItems
Maximum number of output records across all input searches.
Default: 50.
Allowed range: 1 to 5000.
maxPages
Maximum structured result pages fetched for each search.
Default: 10.
Allowed range: 1 to 100.
monitoring
Set to true to compare the current inventory with stored prior state.
stateKey
Required when monitoring is enabled.
Choose a stable private value for one logical monitor, such as brooklyn-rental-watch.
The Actor hashes this value before constructing the key-value store key.
emitUnchanged
Include UNCHANGED records in monitoring runs.
It defaults to false so scheduled runs can produce a compact change feed.
emitRemoved
Emit REMOVED records that existed in a prior complete snapshot but are absent now.
Removal detection is skipped when maxItems or maxPages truncates the current snapshot, preventing false removals.
Output example
A current rental record has this shape:
{"listingId": "5118281","listingType": "rent","url": "https://streeteasy.com/building/97-grand-avenue-brooklyn/4b","street": "97 Grand Avenue","unit": "4B","areaName": "Clinton Hill","price": 4565,"currency": "USD","status": "ACTIVE","daysOnMarket": 0,"listedAt": "2026-07-30T01:05:02.000-04:00","bedrooms": 2,"bathrooms": 2,"brokerName": "Brighton Management","sourceSearchUrl": "https://streeteasy.com/for-rent/brooklyn","changeType": "NEW","previousPrice": null,"observedAt": "2026-07-30T05:29:23.554Z"}
The full dataset also includes update timestamps, coordinates, source classifications, comparison metadata, and the source fingerprint.
How does change monitoring work?
The first run for a new stateKey classifies observed listings as NEW.
Later runs use these values:
NEW: not present in prior state.PRICE_CHANGED: current price differs from prior price.STATUS_CHANGED: source status differs from prior status.UPDATED: another fingerprinted source field changed.UNCHANGED: no fingerprinted field changed.REMOVED: absent from a complete current snapshot.
Use one stateKey per independent search set.
Reusing the same key for unrelated URLs merges their comparison state.
Schedule a StreetEasy price and status monitor
Create an Apify Schedule after a successful first run.
Hourly or daily frequency is usually more appropriate than rapid polling.
A change-feed input can look like this:
{"startUrls": [{ "url": "https://streeteasy.com/for-sale/manhattan" }],"maxItems": 500,"maxPages": 10,"monitoring": true,"stateKey": "manhattan-sale-watch","emitUnchanged": false,"emitRemoved": true}
Connect the schedule to a webhook, Make, Zapier, Slack workflow, or database loader.
Treat REMOVED as an observed absence, not proof that a property sold.
How much does it cost to monitor StreetEasy listings?
The Actor uses pay-per-event pricing.
Each run has a one-time $0.005 start event.
Each accepted listing or change record uses the item event.
The BRONZE item price is $0.0018 before higher-plan volume-tier discounts.
At that price, 20 records cost about $0.041, 100 records about $0.185, and 1,000 records about $1.805 on BRONZE.
These examples cover Actor event charges.
Your Apify plan and platform usage accounting may also apply.
The Console shows the final charge for every run.
No separate event is charged for detail enrichment, monitoring state, or removed records.
Efficient and reliable usage
- Start with 10–20 items before increasing limits.
- Keep all URLs for one logical monitor in the same scheduled Task.
- Use
emitUnchanged: falsewhen downstream systems only need changes. - Use a sufficiently high limit before enabling removed detection.
- Avoid launching many overlapping runs with the same
stateKey. - Keep schedules at a responsible interval.
- Inspect
completeSnapshotwarnings in logs before interpreting removals.
The Actor uses a coherent US residential proxy session because direct and datacenter requests are challenged by the source.
It rotates only after a verified challenge or transient upstream failure.
Limitations and failure behavior
StreetEasy can change its public structured service or anti-bot controls.
A challenged session is retried with a bounded fresh identity.
The run fails after three blocked sessions rather than returning a false successful empty dataset.
Only public all-NYC and borough search URLs are supported in this version.
Neighborhood-specific path parsing and arbitrary search-filter query parameters are not yet translated into structured filters.
StreetEasy may report zero for unknown living area.
daysOnMarket is calculated from the source listing creation timestamp and may not represent cumulative marketing periods across relistings.
Broker names are source-provided labels, not independently verified identities.
Removed records omit property fields that are not retained in monitor state.
Export and integration patterns
Common workflows include:
- Export a one-time Brooklyn rental snapshot to CSV.
- Load Manhattan sale listings into a warehouse for price analysis.
- Send only
PRICE_CHANGEDrecords to a Slack webhook. - Build a daily borough inventory dashboard.
- Join stable IDs across runs to calculate your own observed history.
- Trigger a review when status changes away from
ACTIVE.
The default dataset is backward-compatible with Apify integrations.
Use the overview view for a compact table or fetch all fields through the API.
Run with the Apify API using cURL
curl -X POST \"https://api.apify.com/v2/acts/automation-lab~streeteasy-listing-monitor/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"startUrls": [{"url":"https://streeteasy.com/for-rent/nyc"}],"maxItems": 20,"maxPages": 1}'
Poll the returned run or use the synchronous dataset endpoint when appropriate.
Never commit your Apify token to source control.
Run with JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/streeteasy-listing-monitor').call({startUrls: [{ url: 'https://streeteasy.com/for-sale/manhattan' }],maxItems: 50,maxPages: 2,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Run with Python
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("automation-lab/streeteasy-listing-monitor").call(run_input={"startUrls": [{"url": "https://streeteasy.com/for-rent/brooklyn"}],"maxItems": 20,"maxPages": 1,})items = client.dataset(run["defaultDatasetId"]).list_items().itemsprint(items)
Use StreetEasy data through MCP
Add the Apify MCP server to Claude Code:
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/streeteasy-listing-monitor"
Claude Desktop, Cursor, and VS Code can use this HTTP MCP configuration:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/streeteasy-listing-monitor"}}}
Example prompts:
- "Run the StreetEasy listing monitor for 20 Brooklyn rentals and summarize median asking rent."
- "Snapshot 50 Manhattan sale listings and group them by broker."
- "Run my Manhattan sale monitor and show only price or status changes."
MCP calls use your configured Apify identity and consume the same event pricing as Console or API runs.
Responsible use and legality
This Actor accesses public listing information without logging in.
You are responsible for following StreetEasy terms, Apify policies, applicable database rights, and privacy laws.
Use reasonable schedules and limits.
Do not use the output for harassment, discriminatory housing decisions, unsolicited contact, or attempts to identify private individuals.
Do not assume a public listing is error-free or independently verified.
StreetEasy and its marks belong to their respective owners.
This Actor is an independent tool and is not affiliated with StreetEasy or Zillow Group.
Troubleshooting
Why did the run fail with a blocked-session error?
The source challenged all three bounded US residential sessions.
Wait before retrying and inspect the run log.
Repeated immediate runs can increase challenge rates.
Why are no removed records present?
Removal detection requires a prior state and a complete current snapshot.
Increase maxItems or maxPages until the run is not truncated.
Why is daysOnMarket null or unexpectedly small?
It depends on StreetEasy's current createdAt value.
Relisted inventory may have a new source listing identity and creation time.
Why are unchanged records missing?
Monitoring defaults to a compact change feed.
Set emitUnchanged to true when you need a complete output on every run.
Can I use a listing detail URL as input?
No.
This Actor snapshots supported NYC or borough sale/rental search URLs.
Related Automation Lab Actors
- Zillow Scraper for broader US property marketplace workflows.
- Idealista Listings Monitor for recurring Spain property inventory snapshots.
- Trade Me Property Listing Monitor for New Zealand property listing changes.
Choose one source-specific Actor per marketplace instead of treating records from different platforms as equivalent listings.
Frequently asked questions
Is this a live alerting service?
No.
It produces snapshots and comparison records when a run starts.
Use Apify Schedules and webhooks to create alerts at your chosen interval.
Does it support sales and rentals in one run?
Yes.
Add multiple supported for-sale and for-rent URLs to startUrls.
Does it expose a StreetEasy API?
It exposes normalized results through the standard Apify API, datasets, clients, and MCP integration.
It does not provide credentials or privileged access to a private StreetEasy API.
Does monitoring preserve full history?
The dataset for each run is immutable according to your Apify retention settings.
The private monitor state stores the latest comparison values, not an unlimited event history.
Persist datasets to your warehouse when you need long-term history.