Live change events · San Francisco, California
NEMA cut its advertised floor $248 overnight. A feed puts that in Slack the same day.
Overnight into August 21, 2026 (Pacific time), listing 32687497 — NEMA, the multi-unit building at 8 10th St in SoMa — moved its observed price_min from $3,563 to $3,315: a −$248 (−6.96%) cut between two monitoring passes. It was one of five San Francisco price_min cuts the comparison pass emitted. In a managed feed, a change row like that goes out to Slack or Sheets the same day it is detected. This page is written for SF multifamily yield and acquisitions desks that price concessions and re-trades off asking-rent movement, not for buyer agents hunting a deal.
This is not a Zumper dump. Pass A stored a baseline of the search window without alerting anyone. Pass B re-ran the identical search overnight, compared every listing by stable ID, and emitted only the rows whose tracked rent had moved. Everything unchanged stayed silent.
No form backend, cookies, tracking pixels, or analytics. The email code identifies this case study only after you send the draft.
price_min cuts emitted in one overnight window. Unchanged listings emitted zero rows.The two-pass San Francisco test
The test used the Zumper Rental Scraper build 1.1.20 — the same build currently on the Store. Pass A (run VW3Py0fARVOiaLQ5l) seeded the comparison state for a San Francisco apartment search at 2026-08-21T05:03Z: it stored a fingerprint per listing — rent range, bedroom and bathroom range, canonical URL — keyed by stable listing_id, and delivered no alert. Pass B (run dmmjgJuSoOU1Zj4Gz) repeated the identical search and finished at 2026-08-21T10:16Z — an overnight window in San Francisco, 10:03 PM to 3:16 AM Pacific. It compared each listing against the stored fingerprint and emitted exactly five observed price_min cuts. Everything else stayed silent — including 535 Taylor St (65035849), the cut featured in an earlier window, which held $4,095 across both passes and therefore emitted nothing.
The five real price_min cuts, in one overnight window
Each listing below lowered its observed minimum asking rent (price_min) between the two passes. These five rows are the complete price_min cut output of the comparison — nothing sampled out, nothing added.
| Listing ID | Address | Rent change | Drop | Changed field |
|---|---|---|---|---|
| 32687497 | 8 10th St (NEMA, SoMa), San Francisco, CA | $3,563 → $3,315 | −$248 (−6.96%) | price_min |
| 23611709 | 855 Brannan St, San Francisco, CA | $4,085 → $3,885 | −$200 (−4.90%) | price_min |
| 56534694 | 191 Frederick St, San Francisco, CA | $4,195 → $3,995 | −$200 (−4.77%) | price_min |
| 39863644 | 1390 Market St Ste 107 (Fox Plaza), San Francisco, CA | $3,019 → $2,889 | −$130 (−4.31%) | price_min |
| 56457376 | 300 Anzavista Ave, San Francisco, CA | $3,850 → $3,750 | −$100 (−2.60%) | price_min |
Observed asking rents can change again after the observation time. A building record like NEMA covers several available unit types, so price_min is the advertised floor of a range, not one unit's rent.
Why a yield desk cares about a $100 cut
Individually, a $100 or $130 trim looks like noise. Watched across a submarket, small price_min cuts are how effective-rent softness shows up before it reaches quarterly comps: operators shade the advertised floor first. This window ran from −$100 (−2.60%) at 300 Anzavista Ave to −$248 (−6.96%) at NEMA. A change-only feed gives an acquisitions or asset-management desk the timestamp, the prior price, and the delta per stable listing ID — enough to track how fast a competitor reprices, which submarkets are shading first, and whether an underwriting assumption about market rent still holds this week. A full nightly export of every SF listing tells you none of that without building the diff yourself.
How the comparison works
1. Stable identity
listing_id is the primary identity. A canonical source URL is retained for delivery and inspection.
2. Tracked snapshot
The fingerprint covers rent range, bedroom and bathroom range, and the canonical listing URL.
3. Caller-owned state
Each monitorId gets a separate record in the named zumper-rental-monitor-state store, in the customer's own Apify account.
4. Change-only output
An unchanged listing emits nothing. A price event carries the prior value, the new value, and which field moved.
How a managed feed delivers these events
The delivery workflow calls the Actor on a schedule, reads its dataset, stops when the dataset is empty, and forwards changed rows to the agreed destination. Credentials belong in n8n credential objects, not inside the workflow JSON.
Limits I keep in the product
Five events describe one window, not the SF market. This was a single overnight comparison of one search. It demonstrates change detection on live data; it is not a market report or a rent index.
No removal claim from a capped search. A listing can disappear because the portal reordered the result window. The feed reports new, price, and detail changes; it does not call an absent row “removed.”
Price ranges need context. A building can expose several unit types in one row. The feed preserves the observed minimum and maximum rather than pretending each building has one rent.
Source access is tested before a quote. A working San Francisco run does not prove that every portal, market, or filter is available. Residential proxy or unblocker costs are scoped separately.
Self-serve or managed
You can run the Actor in your own Apify account and wire delivery yourself. A managed package covers a named source set, agreed schema, schedule, delivery target, monitoring, and source repairs.
One proven source
Real-estate pilot
$750 setup + $350/month
- One market and filter set
- Up to 5,000 delivered rows per month
- Daily delivery by default
- Acceptance against a live source sample
Up to three proven sources
Real-estate Growth feed
$1,750 setup + $950/month
- Up to three source and market combinations
- Normalized change schema
- Daily or agreed scheduled delivery
- Source monitoring and bounded maintenance
Apify platform usage, Actor charges, residential proxies, unblockers, and third-party APIs are separate unless a written quote includes a cap. A monthly service starts only after the sample and schema pass the agreed acceptance check.