Scrape Zillow property listings and agent contacts — emails, phones, price history, Zestimate and 70+ fields. This Zillow scraper filters for FSBO, foreclosures, multi family and sold comps, by ZIP code, ZPID or any Zillow URL, across homes for sale, rent and sold. Export to CSV, JSON or Excel.
All notable changes to the Zillow Property & Agent Data Scraper actor are documented here.
The format follows Keep a Changelog .
[2.3.90] - 2026-08-10
Fixed
A failed run no longer prints the raw technical failure text from the service this actor depends
on. That text went into the run log and into the run's storage records, and on a connection
problem it carried that service's address. None of it was ever useful to you. Failures now read as
"the request was refused upstream"; the reasons you can act on are unchanged.
[2.3.89] - 2026-08-10
Added
Your results now show the properties the free plan matched and did not look up. A free run
enriches 15 properties. If the search matched more — a Miami Beach ZIP matched 820 — the results
now carry up to 25 extra rows after your 15, each with not_enriched in the new
enrichmentStatus column and, in whyNotEnriched, the full count: "this search matched 820
properties and the free plan enriches 15 per run, so 805 were left out."
Those rows carry only what the search itself returned — address, price, beds, baths and the
Zillow listing URL. Every column that costs money to look up is empty on them: agent name,
email and phone, Zestimate, tax and sale history, schools, Walk Score.
They are never charged.
A paid run never produces them, and neither does a run started with the demo ZIP.
Until now this fact lived only in the run log, on the live status page and in the run's storage
records. Anyone reading the results through the API or an AI assistant saw 15 properties and no
way to tell "the free plan stopped at 15" from "this ZIP has 15 listings".
Changed
Two columns added to every row: enrichmentStatus and whyNotEnriched. On a property that
was looked up they read enriched and N/A. They are appended at the end of the row, so every
column that existed before keeps its position.
[2.3.88] - 2026-07-30
Fixed
A search Zillow refuses is no longer reported as "no listings here". When Zillow rejects a
search it answers with an error rather than a result set, and the actor was reading that as an
empty area — so a run would finish cleanly, save nothing, and advise you to try a residential ZIP
while sitting on a ZIP with hundreds of listings. The rejection is now shown, in Zillow's own
words, with the filter to change.
Setting a maximum number of bedrooms and a minimum number of bathrooms no longer returns
nothing. Zillow rejects that combination unless a maximum number of bathrooms is also set. The
actor now supplies an upper bound for you; your minimum is unchanged and nothing extra is filtered
out. Every run that hit this returned zero rows.
The ZIP Codes field now understands what people paste into it. A whole comma-separated list in
a single row is split into its ZIP codes, ranges like 07039-07047 are expanded, ZIP+4 codes are
trimmed to five digits, and a copied block of text is unpacked.
Entries that are not US ZIP codes are no longer searched. Web addresses, Canadian postal codes,
county names and street addresses used to be sent to Zillow anyway, which sometimes matched
unrelated homes — in the wrong country — and charged for them. Each is now skipped, named, and
costs nothing.
One unreadable property no longer ends the whole run. If a single listing cannot be saved, it
is reported and skipped and the rest of the run continues, instead of the run failing with
everything lost.
Changed
The free-plan limit of 20 ZIP codes per run is now applied after a pasted list is split, so a list
in one row is counted the same way as 20 separate rows.
[2.3.86] - 2026-07-30
Fixed
URL search now reads the Zillow pages it used to ignore. One in eleven URL-mode runs was
finishing with no rows and no explanation. Four kinds of link were the cause, and all four now
work: a page for one street address (/homes/119-E-Drexel-Ave_rb/, or a /homedetails/ page with
no ZPID number in it) returns that home; a ZIP page (/ocala-fl-34481/) is searched as the ZIP
itself; a state page (/nc/land/) searches the whole state; and a keyword page
(/fl/fixer-upper_att/) applies the keyword and home types written into the URL.
Owner-posted searches return owner-posted listings. A /fsbo/ or /by-owner/ URL was asking
Zillow for the agent-listed pool, so the homes coming back were not the ones the link asked for —
and each of them was billed. Zillow's owner channel also carries new-construction, bank-owned and
auction homes; those are now dropped before enrichment, so you are not charged for them either.
Added
A plain-language note when a link cannot work. Agent and company profile pages list no homes,
and a neighbourhood inside a city is something Zillow shows on the map but will not search on its
own. Both used to end the run at zero with nothing said. The run now names the shape, says which
page to paste instead, and puts the same line in the run's status message for anyone reading over
the API. Nothing is charged either way.
The cost ceiling is printed before anything is fetched, and shown on the live status page, so a
link that covers a whole state cannot surprise you.
[2.3.84] - 2026-07-29
Fixed
ZIP code search now returns homes in the ZIP you asked for. Every ZIP was being turned into
its city before the search ran, so asking for 78704 searched all of Austin: of 25 homes returned,
1 was in 78704. Measured the same way, 60614 returned 3 of 25 and 33139 returned 9 of 25 — and
every one of those homes was billed. Each ZIP is now searched on its own.
The property cap now applies to each ZIP, as its name always said. ZIP codes were searched
five at a time in one combined query, and the cap cut the combined result — three ZIPs with a cap
of 10 returned 10 homes in total, sometimes none at all from the last ZIP. Each ZIP now gets its
own cap. A run with more than one ZIP will return more homes than before, and cost more: the run
now prints its cost ceiling before fetching anything, and the live status page shows it too.
One bad ZIP no longer spoils the others. A ZIP that Zillow cannot search by itself used to
drag the whole group of five down with it, returning unrelated addresses for all of them.
Added
A note when a ZIP has to be searched through its city. A small number of US ZIP codes — PO-box
and non-residential ones — cannot be searched directly. For those the run searches the surrounding
city and keeps only the homes inside your ZIP; the homes it drops are never billed. Which ZIPs this
happened to, and how many rows were dropped, is written to RUN_SUMMARY.zipScope and explained in
plain language in the USER_MESSAGE record.
[2.3.82] - 2026-07-29
Changed
The Store listing now says what this actor returns — agent emails and phones, price history,
Zestimate, schools and 70+ fields per home, searchable by ZIP code, by ZPID list or by any Zillow
URL — and the price line shows the per-property price instead of a generic label.
[2.3.81] - 2026-07-28
Fixed
The "Live status" link now works after a run has finished. It pointed at the run's own
container, which the platform shuts down as soon as the run ends — so opening it later showed
nothing. It now opens the saved copy of the page, which stays available for as long as the run's
storage does.
[2.3.80] - 2026-07-28
Added
New Example tasks section in the README — eight ready-to-run searches you can start in one
click: homes for sale, recently sold, rentals, foreclosures, new construction and agent leads.
[2.3.79] - 2026-07-28
Maintenance build — no user-facing changes.
[2.3.78] - 2026-07-28
Fixed
The run cost now shows your plan's price, not the Free-plan price. Property Data Enriched costs less on paid plans ($0.08 on Free, down to $0.05 on Gold and above), but the live status page and RUN_SUMMARY always quoted $0.08. Both now quote what your subscription actually pays. Your bill is unchanged — only the number the run reported was wrong.
A run budget you set now buys the properties it should. Because the run priced every property at $0.08, a "Max budget (USD)" of $1.00 stopped at 12 properties on a plan where $1.00 covers 20. The budget is now spent at your real price.
Same input shape, output columns, dataset shape, and pricing.
[2.3.76] - 2026-07-06
Changed
Every "Upgrade" link in run messages now says what's behind it: paid plans start at $29/mo with $29 in platform credits, and the link opens your plan page in Apify Console.
Fixed
The completed-screen upgrade box now quotes the current plan price — $29/mo with $29 in platform credits (it showed an outdated $49).
[2.3.75] - 2026-07-06
Added
Zero-result runs now explain themselves. A run that saves 0 properties writes a USER_MESSAGE with the exact cause for that run — the search matched nothing (with ZIP/URL-specific fixes) vs listings were found but none could be enriched — plus a verified starter input and a note that empty results cost nothing. The live status page shows this diagnosis instead of a bare "Scraping Complete!", and the run's status message points API callers at it too.
Runs stopped by a missing or invalid input now say which field to fix. An empty ZIP list, empty ZPID list, empty URL, or unknown mode writes a USER_MESSAGE naming the exact form field, with a starter example. Previously these runs failed with only a log-level error.
Failed runs get a real error screen. The live status page now renders what stopped the run and what (if anything) was saved — previously it kept showing the in-progress view.
RUN_SUMMARY additions: the no_results diagnosis now covers URL and ZPID modes (was ZIP-only), and a new heldBackByFreeCap field reports exactly how many matching listings the free plan's per-run cap clipped.
README: one-click Example tasks section, 6 new FAQ entries (including "Why did my run return 0 properties?" and "Do I pay for runs that return nothing?"), a URL-mode expectation note, and more related actors.
Fixed
The free-plan cap message now reports only what the cap actually held back. Its "left behind" number previously included delisted listings and failed lookups; it now counts exactly the listings clipped by the per-run cap, and the ZIP-cap note no longer appears on runs that returned nothing (those get the zero-result diagnosis instead).
The paid-plan welcome note no longer appears on a failed run, and failed runs no longer consume a slot toward it.
Stale input hints refreshed: the URL field now mentions plain city/browse URLs (supported since 2.3.70), and the ZIP field no longer claims a 5-ZIP limit.
Same input shape, output columns, KVS record keys, and pricing.
[2.3.73] - 2026-07-06
Fixed
The "Upgrade" link in run summaries now opens your Apify plan page directly (the old link form could land on the wrong billing tab).
[2.3.72] - 2026-06-11
Added
Free-plan runs now report exactly what was held back — when a free-plan ceiling fires (property cap, ZIP cap, per-run budget, masked agent emails), the run writes a USER_MESSAGE storage record with the real numbers for that exact search: how many matched properties were not enriched, how many ZIP codes were not searched, and how many agent emails were found but masked. Previously these limits applied silently and only appeared as ids in FREE_LIMITS_APPLIED.
Changed
Free plan now includes 15 runs per calendar month (resets on the 1st; demo/test runs don't count). Runs over the allowance complete successfully with a clear message and charge nothing. Paid plans are unlimited, as before. Per-run free limits (15 properties / 20 ZIP codes / masked emails) are unchanged.
Same input shape, output columns, and pricing.
[2.3.71] - 2026-05-21
Added
Plain city URLs now work in URL mode — paste a Zillow city link such as https://www.zillow.com/austin-tx/ or https://www.zillow.com/austin-tx/houses/ and the actor reads it as a location search; previously these completed with zero results unless you first applied a filter on Zillow. The home-type and listing segments — /houses/, /condos/, /townhomes/, /apartments/, /multi-family/, /lots-land/, /manufactured/, /sold/, /rentals/, /fsbo/ — are mapped to the matching search. searchQueryState, _rb browse, recently-sold, and single-property /homedetails/.../<zpid>_zpid/ URLs are unaffected.
Same input shape, output columns, KVS records, and pricing.
[2.3.70] - 2026-05-21
Fixed
Plain Zillow browse URLs now work in URL mode — for-sale browse URLs like https://www.zillow.com/homes/Beverly-Hills,-CA_rb/ are now read as a location search (previously they returned no results). Recently-sold, searchQueryState, and single-property /homedetails/.../<zpid>_zpid/ URLs are unaffected; single-address shortcut URLs still return the existing guidance to use ZPID mode.
Same input shape, output columns, KVS records, and pricing.
[2.3.68] - 2026-05-19
Fixed
Apartment-building rentals now emit useful data — multi-unit ForRent listings on Zillow are returned by the search endpoint with a lat-long fallback identifier (isBuilding: true, e.g. zpid "30.249971--81.81388") because Zillow doesn't assign stable property IDs to multi-unit rental buildings. The detail-enrichment endpoint (/property?zpid) can't process those identifiers — so the actor was pushing 13 of 15 nearly-empty rows on a representative Jacksonville rentals search (customer-reported 2026-05-19, run IzeGJd41kJD8l4q8N: 15 enriched, only 1 with brokerName, 14 effectively empty). The actor now detects isBuilding: true and emits a row directly from the search-result payload: brokerName = building name, streetAddress / city / state / zipcode parsed from the address, price = lowest unit rent, propertyDescription = unit-floorplan summary, plus new fields availabilityCount and unitsAvailable (additive dataset_schema additions). Skips the doomed detail call entirely — saving an API hop per building.
Changed
dataset_schema.json — added two additive fields, availabilityCount (integer / null) and unitsAvailable (array / null), populated only for apartment-building rentals. brokerName description updated to call out the building-name-as-listing-company semantics for those rows.
Same input shape, output columns are a superset of the previous shape (two new fields), KVS records, and pricing are unchanged. Single-property ForSale/ForRent/RecentlySold/ZPID-mode rows are unaffected.
[2.3.67] - 2026-05-19
Fixed
Sale-channel routing bug for ForRent searches — the historical "catch-all" otherListings=true parameter sent when both isForSaleByAgent and isForSaleByOwner had the same value silently collapses ForRent searches to zero results upstream. Empirically verified on ZIP 32218: otherListings=true → 0 properties; explicit saleByAgent=true&saleByOwner=true → 41 properties. The "else" branch in the sale-channel router now sends both flags explicitly as true, which works for both ForSale and ForRent. This was the root cause of the recurring "took form defaults, still got zero" rental complaints — including the customer-reported run on 32218 that motivated the 2.3.63 → 2.3.65 patch sequence.
Same input shape, output columns, KVS records, and pricing.
[2.3.65] - 2026-05-19
Fixed
Rental search default-fix — sale-flags clearing bug — 2.3.64 set isForSaleByAgent and isForSaleByOwner to explicit false when clearing the form defaults. Empirically the upstream listings API returns 0 results when both are explicit false but returns the full inventory when the keys are simply absent — even though the actor's own L1676 conditional treats both cases identically. Smoke verified on ZIP 32218 ForRent: explicit false → 0 properties; key absent → 41 found / 5 returned. Auto-fix now deletes the keys instead of setting them to false. No change to the trigger gate.
Same input shape, output columns, KVS records, and pricing.
[2.3.64] - 2026-05-19
Changed
Rental search default-fix — extended — the auto-fix introduced in 2.3.63 also now clears the form-default sale-side listing flags (isForSaleByAgent: true + isForSaleByOwner: true) on ForRent searches when they match the form-default signature. Smoke-replay of the customer-reported zero-result run on ZIP 32218 showed apartments-on alone wasn't enough — the sale-side flags also poisoned the rental query and had to be cleared for the result set to recover. Same trigger gate (both flags both default to true together = form default; explicit selection of one side only is left alone).
Same input shape, output columns, KVS records, and pricing.
[2.3.63] - 2026-05-19
Changed
Rental search default-fix — ZIP mode now auto-enables the "Apartments" home type when it detects you took the form defaults on a ForRent search (i.e. Houses + Townhomes + Condos + Multi-family all on, Apartments off). The original defaults are tuned for ForSale where apartments are rare; for rentals apartments are the majority of inventory, and the same defaults were yielding ~83% zero-result rate vs ~20% with apartments on. If you really want SFR-only rentals, set isApartment=false together with the other home types you want off — the auto-fix only triggers on the exact form-default signature.
Input schema — isApartment field description rewritten to call out the rental-search best practice and explain the auto-fix.
Same input shape, output columns, KVS records, and pricing. URL and ZPID modes unchanged (URL mode reads filters from searchQueryState; ZPID mode bypasses filters entirely).
[2.3.62] - 2026-05-19
Changed
URL mode — clearer error when zillowUrl is missing (now includes an example URL, how to obtain one, and the SDK call shape). Added a pre-flight warning when the URL looks like a single-address shortcut (e.g. /homes/<address>_rb/) — those redirect on Zillow's side and never return listings, so the warning points to the right alternative before the upstream call. Added a tip when a /homedetails/.../<zpid>_zpid/ URL is auto-converted to ZPID mode, suggesting the direct ZPID input as the cleaner shape for future runs.
RUN_SUMMARY — added properties.capStatus (unlimited_complete / cap_reached / no_results) and properties.capNote so consumers reading the run via the API can tell the difference between "this is the full upstream inventory" and "we hit the cap, more available." The same note is also logged to the run console. ZIP mode only. Solves the recurring confusion where users widen filters expecting more results and keep getting the same count.
Input schema — zillowUrl field description rewritten to explain the search-URL requirement (must contain searchQueryState=) and point single-property users to ZPID mode.
Same input shape, output columns, KVS records, and pricing.
[2.3.61] - 2026-05-11
Changed
README — Dropped the entire Tips & Best Practices section (64 lines, 4 sub-sections). Same input, output, and pricing.
[2.3.60] - 2026-05-11
Changed
README — Dropped the standalone Choose your mode (28 lines, 3 sub-sections) and How to use it (in one screen) (9 lines) H2 sections. The three modes (ZIP / ZPID / URL) are now summarized in a compact 3-row table at the top of What it does. Trims 33 lines and 3 sub-sections; same input, output, and pricing.
[2.3.59] - 2026-05-08
Changed
Maintenance build — no user-facing changes.
[2.3.58] - 2026-05-07
Changed
README — refreshed structure for clarity (restored prior section layout). Same input, output, dataset shape, and pricing.
[2.3.57] - 2026-05-07
Changed
README — aligned to Apify quality template. Hero rewritten with value-first prose and a "beyond what Zillow's official API offers" comparison; numbered 3-step Quick start; new 🛟 Support & feedback section pointing to Apify Store reviews / bookmark / Issues tab; promoted disclaimer to dedicated ⚖️ Is it legal to scrape Zillow? H2 with link to Apify's web-scraping legality blog; FAQ expanded to 12 Q&As (including legality, ban risk, data freshness, per-run cost cap); output sample trimmed to the 25 most-used keys with a "+49 more in the dataset" note; tightened Tips & Best Practices to 4 sub-sections × 3 bullets. No functional changes — same input, output, dataset shape, and pricing.
[2.3.56] - 2026-05-07
Changed
Top-level input-schema description reformatted to a 3-bullet layout — each step on its own line, bold labels (Choose Operation Mode | Inside Selected Mode | Tuning), and a link to the README's Tips & Best Practices anchor for cost / performance / data-quality guidance.
Fixed
README — removed unverified "Off-peak hours tend to have warmer upstream caches" claim from the Tips & Best Practices Performance section. The actor's runtime isn't tied to time-of-day; the surviving performance guidance (per-call upstream timeout, ZIP-batch dedup) lives under a renamed Batching & Bounds sub-block.
[2.3.55] - 2026-05-07
Changed
Top-level input-schema description rewritten to mirror the README's new "How to use it" decision flow (Choose Operation Mode → fill mode-specific input → tune ⚙️ Enrichments + 🔬 Filters). Customers and AI agents reading the schema now see the same 3-step framing as the README, instead of a flat enumeration of modes. Length 322 → 438 chars (in band, ≤500). No code or input-field changes.
[2.3.54] - 2026-05-07
Changed
README — added a 🧭 How to use it (in one screen) decision flow above the per-mode deep dives (Choose Operation Mode → Inside Selected Mode → Tuning) plus a full 💡 Tips & Best Practices section before the FAQ (4 sub-sections: Getting Maximum Results, Cost Optimization, Performance, Data Quality). Customers were getting lost between ZIP / ZPID / URL modes — the new top-of-page flow makes the mode-decision and the per-mode required fields visible in one screen, and the Tips block consolidates cost-capping, sold-listings-defaults, nullable-column, and SKIPPED_ITEMS patterns that previously lived only in inline tips. No code changes.
[2.3.53] - 2026-05-07
Fixed
photos[] column was returning only the main listing photo (single-element array) when enrichPhotos: true was set. Root cause: the upstream photos endpoint returns a {images: [url1, url2, ...]} envelope, but the mapping code expected a top-level array of photo objects. Customers toggling the flag have been getting [mainPhoto] instead of the full gallery since the feature shipped. New code handles both shapes (envelope and array) and both string and object items.
[2.3.52] - 2026-05-07
Fixed
walkScore, transitScore, and bikeScore columns are no longer silently null when enrichWalkScore is enabled. The mapping accessor was reading .score on the upstream response, but the upstream uses distinct lowercase keys per metric (walkscore / transit_score / bikescore) — three columns had been emitting null on every enriched row since the feature shipped. New fallback chain (?.walkscore ?? ?.score ?? null, etc.) keeps it forward-compatible if the upstream ever switches to a unified .score key.
[2.3.51] - 2026-05-07
Changed
Related actors section now lists the full Zillow family — zillow-url-search (paste any Zillow search URL) and zillow-mcp-server (MCP integration for Claude Desktop / Cursor / ChatGPT) added alongside the existing zillow-zip-search row.
[2.3.50] - 2026-05-06
Changed
Related actors section now lists only Zillow-domain actors. Replaced the cross-domain narrative paragraph (Instagram / TikTok / YouTube author-profile pitch) with a 2-row table that surfaces the lighter single-mode zillow-zip-search spinoff as the natural alternative for users who only need ZIP-code input. Discoverability win for both actors — visitors landing on the multi-mode parent now see the simpler ZIP-only option without leaving the page.
[2.3.49] - 2026-05-06
Fixed
Per-field output documentation now visible in the Apify Console and to API/MCP clients. The 74-column dataset schema (titles, descriptions, types, examples for every output field) shipped with 2.3.43 had been silently ignored because .actor/actor.json carried an inline display-only block instead of pointing to ./dataset_schema.json. AI agents reading the dataset shape via API and visitors browsing the Console dataset view now see the same per-column documentation that's always been on disk.
Widened lotAreaValue and daysOnZillow type unions to include string. Both columns occasionally come back from the upstream feed as pre-formatted strings instead of raw numbers; the previous integer/number/null union rejected those rows, producing zero dataset items in the brief window after the wiring fix above and before this build. No change to dataset shape — strings have always been emitted in those columns when upstream returned them.
[2.3.47] - 2026-05-06
Added
Test-run cap on demo input. ZIP-mode runs that leave the ZIP code at the example value 90210 and don't set any filters now cap output at 10 properties (~$0.80 max on FREE tier, ~$0.50 on DIAMOND), making "Try" runs predictable on any plan. Previously, paid customers experimenting with the default seed could trigger uncapped enrichment of however many listings 90210 currently returns ($4–14+ per trial). A console banner explains the cap, and a USER_MESSAGE Storage record with id test_run_default_input_v1 makes the same explanation visible to API-origin runs that never open the run console.
The cap is restored to the normal plan limit (paid: unlimited; free: 15 properties / run) as soon as you change the ZIP code, add at least one filter, or switch to ZPID list / Zillow URL mode.
[2.3.46] - 2026-05-06
Fixed
Same property no longer appears multiple times in the dataset when input ZIPs resolve to overlapping locations. Previously, ZIP-code mode runs whose input ZIPs all mapped to the same city (e.g., 20 Manhattan ZIPs → "New York, NY") fired the same search query once per batch of 5 ZIPs and re-emitted the same listings each time, charging the per-property paid event multiple times for one property. The actor now (a) skips a batch entirely when its ZIPs are already covered by an earlier batch's resolved location, and (b) tracks already-processed zpids and skips re-enrichment if the same property is returned by two different searches.
ZPID-mode runs that pass the same zpid more than once (e.g., a list with accidental duplicates) now charge & emit the property once instead of once per occurrence. Duplicate ZPIDs are recorded in SKIPPED_ITEMS with category duplicate.
[2.3.45] - 2026-05-05
Fixed
URL-mode runs no longer hang for the full platform timeout when an upstream listings request stalls. Each fetch attempt is now bounded at 15 seconds so transient slowdowns surface as a normal retry/error instead of a 12-minute run abort. Same bounding applies to ZIP / ZPID modes — latent there because their endpoints are cache-warmer.
[2.3.44] - 2026-05-05
Fixed
ZIP-code mode now reliably returns listings for every covered ZIP. Previously, ZIP codes that the upstream listings provider did not recognize as a "named place" (most rural and small-town ZIPs, e.g. 20101 Aldie VA, 60019 Des Plaines IL) silently returned zero results — the run completed without errors but produced an empty dataset. The actor now resolves each ZIP to its city/state via a bundled US locality database before searching, and accepts both standard and minimal upstream response shapes. Customers using these ZIPs will start getting data on their next run.
ZIPs that aren't in the US locality database (rare P.O.-only or unassigned codes such as 10809, 11617, 12425) are now recorded in the SKIPPED_ITEMS storage record with category not_resolvable and a clear instruction to use a wider area / city name, instead of silently returning empty.
[2.3.43] - 2026-05-04
Changed
README restructured to the LLM-discoverability template (16 sections, ~370 lines). Added an Apify status badge, an output sample inside the first 25 % of the page, a pay-per-event pricing table (replacing the older Compute-Units prose), a Free-vs-paid table, dedicated Resume / Storage Records / Programmatic-API sections, and a tighter Related-actors pointer.
Every output column now has a per-field description, type, and example available in the Apify Console's dataset view and to clients that read the actor schema programmatically — covers all 74 emit-able columns across the 3 operation modes (ZIP / ZPID / URL).
Top-level Input description rewritten to lead with the 3-mode positioning and pay-per-event pricing model so agent clients pick the right mode without reading the full schema.
SEO description tightened on the Apify Store page (no functional change).
[2.3.42] - 2026-05-03
Fixed
The USER_MESSAGE Storage record (welcome banner on a paid user's 1st run, check-in on the 3rd) now reliably lands. Previously it silently degraded to a no-op due to a per-actor named-storage scoping issue specific to this account.
[2.3.41] - 2026-05-03
Added
New SKIPPED_ITEMS Storage record listing every zpid / ZIP / URL skipped during the run, with reason and category (filter, not_found, error, free_limit). Open the Storage tab → SKIPPED_ITEMS to see exactly which items hit which reason, and which ones errored (re-run those — most errors are transient). The Log also prints up to 3 examples per category at the end of the run.
New FREE_LIMITS_APPLIED Storage record on free-plan runs that hit any of the free-tier ceilings (15-property cap, 20-ZIP cap, $1.20 budget, agent-email masking). Each entry has a stable id code for programmatic consumption. Empty/omitted on paid runs.
New USER_MESSAGE Storage record on a paid user's 1st and 3rd paid run — short onboarding/check-in tips, also embedded in RUN_SUMMARY.
[2.3.38] - 2026-05-01
Fixed
Empty mode-specific input fields (ZIP Codes / ZPID List / Zillow Search URL) now exit with a "Configuration Error" stop reason instead of an unhandled error message, so it's clearer that the run was rejected due to input rather than an actor crash. Run still ends with FAILED status — only the message text changes.
[2.3.37] - 2026-04-30
Fixed
Lifted the hard cleanup deadline from 30 seconds to 60 seconds. With every finalize step now bounded by 2.3.36's 3-second timeouts, normal post-processing budget is roughly 12 seconds of bounded finalize plus the existing 20-second completed-screen display, which was bumping into the 30-second deadline; the 60-second window leaves comfortable headroom while still terminating any truly stuck run well before the 180-second platform timeout.
[2.3.36] - 2026-04-30
Fixed
Bound every async finalization step (run-summary write, run-metadata fetch, first-run timestamp, analytics POST, status-page write) with a 3-second timeout each. Previous attempts assumed only the non-default key-value-store helpers stalled, but logs showed finalization hanging silently before those calls; bounding all of them ensures the run reliably exits within ~25 seconds of "Processing complete!" without falling back to the force-exit safety net.
[2.3.35] - 2026-04-30
Fixed
Bounded the non-default key-value-store calls inside the analytics helpers with a 3-second timeout each, so they fail fast under LIMITED_PERMISSIONS instead of hanging silently.
[2.3.34] - 2026-04-30
Fixed
Added a 30-second cleanup safety net so runs always terminate, even if the post-run analytics or key-value-store calls stall silently. Prevents the run from hitting the 180-second platform timeout when finalization paths hang on permission errors.
[2.3.33] - 2026-04-30
Maintenance build — no user-facing changes.
[2.3.32] - 2026-04-30
Fixed
Followup to 2.3.31: closing the Live View server alone was not enough — keep-alive sockets from outbound HTTP fetches also held the event loop open. Added explicit Actor.exit(0) after the completed-screen window so the run terminates promptly. Completed runs now show SUCCEEDED within ~25 seconds of "Processing complete!" instead of hitting the 180-second hard timeout.
[2.3.31] - 2026-04-30
Fixed
Run no longer hangs ~160 seconds after "Processing complete!" before exiting. The Live View web-server's existing connections are now actively closed before shutdown, so runs terminate within ~20 seconds of completion (the existing completed-screen display window) instead of hitting the 180-second hard timeout. Affects user-visible run status: completed runs now show SUCCEEDED instead of TIMED-OUT.
Changed (internal)
Analytics runStatus field is now computed locally (SUCCEEDED/FAILED) rather than read from the still-in-progress runs/last metadata, which was reliably empty during the analytics POST.
[2.3.30] - 2026-04-29
Maintenance build — no user-facing changes. Internal analytics fixes only;
input schema, output dataset columns, KVS records, console output, error
messages, defaults, and pricing are all unchanged from 2.3.29.