# Changelog of Zillow ZIP Code Property Scraper (`afanasenko/zillow-zip-search`) Actor

- **URL**: https://apify.com/afanasenko/zillow-zip-search/changelog.md
- **Full Actor documentation**: https://apify.com/afanasenko/zillow-zip-search.md

## Changelog

All notable changes to **Zillow ZIP Code Property Scraper** are documented here.
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

### \[0.0.38] - 2026-09-23

#### Fixed

- **A run now stops at its "Maximum cost per run".** When that limit, or what is left of your
  account's usage limit, is used up, the run stops enriching and keeps every property it charged
  for. Its message and status say how many properties the limit paid for and how to get the rest.
  Properties it didn't reach are listed in `SKIPPED_ITEMS` and aren't charged.

### \[0.0.37] - 2026-09-10

#### Changed

- Clarified wording in the README, in two output column descriptions and in older entries of this
  changelog. Nothing changes in how the actor runs, what it returns or what it costs.
- When a run fails for a reason on our side, the error message now stays short and plain.

### \[0.0.36] - 2026-08-18

Maintenance build — no user-facing changes. Input schema, output dataset
columns, KVS records, console output, error messages, defaults, and pricing
are all unchanged from 0.0.35. Saved tasks continue to work identically.

### \[0.0.35] - 2026-08-17

Maintenance build — no user-facing changes. Input schema, output dataset
columns, KVS records, console output, error messages, defaults, and pricing
are all unchanged from 0.0.34. Saved tasks continue to work identically.

### \[0.0.34] - 2026-08-17

Maintenance build — no user-facing changes. Input schema, output dataset
columns, KVS records, console output, error messages, defaults, and pricing
are all unchanged from 0.0.33. Saved tasks continue to work identically.

### \[0.0.33] - 2026-08-17

Maintenance build — no user-facing changes. Input schema, output dataset
columns, KVS records, console output, error messages, defaults, and pricing
are all unchanged from 0.0.32. Saved tasks continue to work identically.

### \[0.0.32] - 2026-08-10

#### Fixed

- **A failed run no longer prints raw technical failure text.** That text went into the run log and
  into the run's storage records, and on a connection problem it carried a server address. None of
  it was ever useful to you. Failures now read as one short, plain sentence; the reasons you can act
  on are unchanged.

### \[0.0.31] - 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 ZIP — 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.
- **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.

#### 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.

### \[0.0.29] - 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.

### \[0.0.27] - 2026-07-29

#### Changed

- **The Store listing now says what this actor returns** — address, price, beds and baths, agent
  name, email and phone, Zestimate, schools, photos and price history, across homes for sale, for
  rent and sold — and the price line shows the per-property price instead of a generic label.

### \[0.0.26] - 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.

### \[0.0.25] - 2026-07-28

Maintenance build — no user-facing changes.

### \[0.0.24] - 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.

### \[0.0.22] - 2026-07-06

#### Added

- Zero-result diagnosis: any completed run that saves 0 properties now writes a `USER_MESSAGE` record naming the exact cause (empty/non-residential ZIP vs listings that could not be enriched) and the fix, with a verified starter ZIP. The run's status line points to it, so API and AI-agent consumers see it too.
- Input-error coaching: a run failed by an empty ZIP Codes field now explains which form field to fix and confirms nothing was charged (previously a bare error).
- Failed runs now render a proper error screen on the live status page instead of a perpetually refreshing progress view.
- Free-plan cap interrupts with the real numbers: when the per-run property cap, ZIP-count cap, budget ceiling, or email masking held results back, the run now reports exactly how much was held back (or says so honestly when the search does not report a total) and what a paid plan would have returned.
- Free plan now includes 15 runs per calendar month (demo runs don't count); the allowance and its reset date are explained in-run when reached.
- Run summary now reports how many listings the search matched, the held-back count, and ZIPs requested vs searched, so capped runs are distinguishable from complete ones.
- Demo-input runs that hit the test cap now say so in the run summary (previously silent).
- README: example task pages, three new FAQ entries, expanded related-actors table.

#### Fixed

- Paid onboarding no longer fires (and the run counter no longer advances) on failed runs.
- The review link on the completed screen pointed at the parent actor's page — now links to this actor.
- Stale "$49/mo" plan hint on the completed screen — paid plans start at $29/mo.
- Free-plan budget messages now quote the run's actual budget instead of a hardcoded default.

Same input shape, output columns, KVS record keys, and pricing.

### \[0.0.21] - 2026-06-11

#### Changed

- Maintenance build — no user-facing changes.

### \[0.0.20] - 2026-06-10

#### Fixed

- **monday.com export: agent phone numbers now import correctly** — phone columns require a structured value; plain strings made the item creation fail (the run itself was unaffected — export is best-effort by design).

### \[0.0.19] - 2026-06-10

#### Added

- **Two new export destinations: Airtable and monday.com** — both authorize with a one-click OAuth popup, same as Notion. Airtable exports land as a new table in an auto-created `Apify Exports` base (up to 500 rows per run); monday.com exports create a board with typed columns (up to 50 items per run). The success message now links straight to the created table / board / database.

### \[0.0.18] - 2026-06-10

#### Changed

- **Workspace export now targets Notion only** — Supabase support is removed: its setup required a personal access token and project selection, which proved too cumbersome compared to Notion's one-click authorization. Runs that still pass `exportSupabaseProjectRef` get a clear note that the field is ignored. More one-click destinations are planned.

### \[0.0.17] - 2026-06-10

#### Changed

- **Cleaner input form** — the `exportSupabaseProjectRef` field no longer appears in the visual input editor (it was relevant only to Supabase multi-project accounts but showed for everyone). It still works when set through the JSON input editor or the API; the run's error message explains exactly when and how to use it.

### \[0.0.16] - 2026-06-10

#### Added

- **Export to your own workspace via MCP connectors** — pick an authorized connector in the new "Export destination" input field and the run delivers its property rows to your Supabase database (up to 500 rows, `apify_zillow_zip_search` table) or Notion workspace (up to 100 rows, auto-created database) when scraping completes. One-time connector setup happens in Apify Console under Settings → API & Integrations; your credentials never enter the actor. Export is best-effort — it never changes scraping results, and runs without a connector behave exactly as before. New optional field `exportSupabaseProjectRef` selects the target project when your Supabase account has several.

Same input shape (two new optional fields), same output columns, same pricing.

### \[0.0.14] - 2026-05-19

#### Fixed

- **Apartment-building rentals now emit useful data** — for ForRent searches that return multi-unit apartment buildings (identified only by a lat-long fallback identifier), the actor now emits a row directly from the search result instead of pushing empty rows from a property-details lookup that could not succeed. `brokerName` = building name, plus address fields parsed from the listing address, `price` from the lowest unit rent, `propertyDescription` summarising floorplans. New additive fields `availabilityCount` and `unitsAvailable` carry unit-level detail. Ported from parent zillow-scraper 2.3.69.

Same input shape, output is a superset (two new fields), same pricing.

### \[0.0.13] - 2026-05-19

#### Fixed

- **Sale-channel routing bug for ForRent searches** — when both `isForSaleByAgent` and `isForSaleByOwner` had the same value, the actor asked for a catch-all listing channel that silently returns zero results on ForRent searches. The actor now always asks for both explicitly in that case, which works for both ForSale and ForRent. Ported from parent zillow-scraper 2.3.66.

Same input shape, output columns, KVS records, and pricing.

### \[0.0.12] - 2026-05-19

#### Fixed

- **Rental search default-fix — sale-flags clearing bug** — 0.0.11 set the cleared flags to explicit `false` instead of leaving them unset. The search returns 0 results when both are explicitly `false`, but the full inventory when both are left unset. The auto-fix now leaves both unset. Ported from parent zillow-scraper 2.3.65.

Same input shape, output columns, KVS records, and pricing.

### \[0.0.11] - 2026-05-19

#### Changed

- **Rental search default-fix — extended** — the auto-fix introduced in 0.0.10 also now clears the form-default sale-side listing flags (`isForSaleByAgent: true` + `isForSaleByOwner: true`) on `ForRent` searches when they match the form-default signature. Ported from parent zillow-scraper 2.3.64.

Same input shape, output columns, KVS records, and pricing.

### \[0.0.10] - 2026-05-19

#### Changed

- **Rental search default-fix** — 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.

Ported from parent zillow-scraper 2.3.63. Same input shape, output columns, KVS records, and pricing.

### \[0.0.9] - 2026-05-19

#### Changed

- **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 every listing the search found" and "we hit the cap, more available." The same note is also logged to the run console. Solves the recurring confusion where users widen filters expecting more results and keep getting the same count.

Same input shape, output columns, KVS records, and pricing.

### \[0.0.8] - 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; replaced shields.io placeholder badge with the proper Apify Actor badge; numbered 3-step Quick start; new `💡 Tips & Best Practices` section (4 sub-sections × 3 bullets); promoted disclaimer to dedicated `⚖️ Is it legal to scrape Zillow?` H2 with link to Apify's web-scraping legality blog; FAQ expanded to 11 Q\&As (added ban risk, data freshness, cost cap, run speed); output sample trimmed from 100+ lines to the 25 most-used keys with a "+49 more in the dataset" note; refined `🛟 Support & feedback` section to template format. No functional changes — same input, output, dataset shape, and pricing.

### \[0.0.7] - 2026-05-07

#### Fixed

- `walkScore`, `transitScore`, and `bikeScore` columns are no longer silently null when `enrichWalkScore: true`. The actor was reading the three scores under the wrong names and getting null. Three columns had been emitting null on every enriched row since the feature shipped.
- `photos[]` column was returning only the main listing photo (single-element array) when `enrichPhotos: true`. The photo gallery arrived in a different shape than the actor expected, so it silently fell back to the main photo only. Customers toggling the flag have been getting one photo instead of the full gallery since the feature shipped.

Both fixes ported 1:1 from parent zillow-scraper 2.3.52 + 2.3.53.

### \[0.0.6] - 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 parent and this actor's existing rows.

### \[0.0.5] - 2026-05-06

#### Changed

- **Related actors section now lists only Zillow-domain actors.** The previous table also pointed to Instagram and TikTok scrapers, which don't help anyone scraping real estate. The section now shows a 2-row decision matrix: this actor (single-mode ZIP code) and the multi-mode parent (ZIP + ZPID + URL).

### \[0.0.4] - 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) inherited from the parent 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 per-column documentation that's always been on disk.
- **Widened `lotAreaValue` and `daysOnZillow` type unions to include `string`** (mirrored from parent zillow-scraper 2.3.49). Both columns occasionally come back from Zillow as pre-formatted strings instead of raw numbers; the previous integer/number/null union rejected those rows. No change to dataset shape — strings have always been emitted in those columns when Zillow reported them that way.

### \[0.0.3] - 2026-05-06

#### Added

- **Test-run cap on demo input.** 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.

#### Changed

- The cap is restored to the normal plan limit (paid: unlimited; free: 15 properties / run) as soon as you change the ZIP code or add at least one filter.

### \[0.0.2] - 2026-05-06

#### Changed

- Output sample in the README is now the full row (all 74 columns) from a real run, instead of a 26-field excerpt. Long narrative fields (`propertyDescription`, `priceHistory`) are condensed for readability; everything else is shown verbatim with notes on which columns commonly come back as `null` and which require `enrichWalkScore` / `enrichPhotos` to populate.

### \[0.0.1] - 2026-05-06

#### Added

- Initial release of Zillow ZIP Code Property Scraper.
- Search Zillow listings by US ZIP code with filters for price range, beds/baths, square footage, lot size, year built, home type (single family / townhouse / condo / multi-family / manufactured / lot-land), listing status (For Sale / For Rent / Recently Sold), days on Zillow, keywords, school ratings, and 50+ property features (pool, garage, view, basement, 3D tour, waterfront, etc.).
- Optional enrichment: Walk Score / Transit Score / Bike Score and full photo gallery URLs.
- Free plan limits: up to 20 ZIP codes per run, up to 15 properties per run, $1.20 per-run budget, agent email domains masked.
- Live status page (HTML) and `RUN_SUMMARY` Key-Value Store record at end of every run.
- Skipped-items audit (`SKIPPED_ITEMS` KVS record) listing every ZIP and property skipped during the run with reason and category (`filter`, `not_found`, `error`, `free_limit`, `not_resolvable`).
- Free-tier ceiling tracking (`FREE_LIMITS_APPLIED` KVS record) — empty/omitted on paid runs.
- Onboarding banner (`USER_MESSAGE` KVS record) shown to paid users on their 1st and 3rd paid run.
- Unknown-input-keys diagnostic (`UNKNOWN_INPUT_KEYS` KVS record) — surfaces input field names that were silently dropped because they don't belong to this actor's schema (common when copy-pasting input from other Zillow scrapers).
- Pay-per-event pricing: $0.08–$0.05 per property enriched, tiered by Apify plan (FREE → DIAMOND), plus $0.00005 per actor start (one-time, per GB of memory).
