# Changelog of Zillow URL Search Property Scraper — Sold Homes, Search Results (`afanasenko/zillow-url-search`) Actor

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

## Changelog

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

### \[0.0.30] - 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.29] - 2026-09-23

#### Fixed

- A ZIP code page without a city in front of it (for example `https://www.zillow.com/90210/rentals/`) is now searched as that ZIP code; before, the run stopped saying the link could not be read.
- A search link copied after moving Zillow's map, with no city or ZIP in it, now returns homes inside the map area it shows.
- If a run cannot start because of a problem on our side, the Output tab now says the run stopped instead of loading forever.

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

#### Changed

- Clarified wording in the README, the changelog and the output field descriptions. 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.27] - 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.26. Saved tasks continue to work identically.

### \[0.0.26] - 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.25. Saved tasks continue to work identically.

### \[0.0.25] - 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.24. Saved tasks continue to work identically.

### \[0.0.24] - 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 leave out the raw reply and the server address; the reasons you
  can act on are unchanged.

### \[0.0.23] - 2026-07-30

#### Fixed

- **A search Zillow refuses is no longer reported as an empty URL.** When Zillow rejects a search it
  answers with an error rather than a result set, and the actor was reading that as a link with no
  listings behind it — so the run advised you to re-copy a URL that was already fine. The rejection
  is now shown, in Zillow's own words, with the filter to change on the Zillow page.
- **A URL carrying 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.
- **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.

### \[0.0.21] - 2026-07-30

#### Fixed

- **Six kinds of Zillow link now work where five of them used to return nothing.** A page for one
  street address (`/homes/4500-SE-18th-Ave-Ocala-FL-34480_rb/`, or a `/homedetails/` page with no
  ZPID number) returns that home. A ZIP page (`/ocala-fl-34481/`) is searched as the ZIP itself, so
  the homes come back inside it. A state page (`/nc/land/`) covers 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 sending
  a request that returns zero homes for every listing status, so those links always came back empty.
  Zillow's owner channel also carries new-construction, bank-owned and auction homes; those are now
  dropped before enrichment, so the rows you are charged for are the owner-posted ones.

#### Changed

- **The note shown when a link cannot work now names the shape.** It used to say state-level and
  address-only URLs never work — both of them do now. Agent and company profile pages, and
  neighbourhoods Zillow will not search on their own, are what remains: the run ends at zero rows,
  charges nothing, and says which page to paste instead.

#### Added

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

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

#### Changed

- **The Store listing now says what this actor returns.** The summary names Zillow and the fields
  that come back — address, price, beds and baths, agent name, email and phone — instead of counting
  the filters it supports, and the price line shows the per-property price instead of a generic
  "Pay per event" label. Same input shape, output columns, dataset shape and pricing.

### \[0.0.18] - 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.17] - 2026-07-28

Maintenance build — no user-facing changes.

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

Same input shape, output columns, dataset shape, and pricing.

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

#### Added

- **Every zero-result run now explains itself.** A run that saves 0 properties writes a plain-language `USER_MESSAGE` record naming the exact cause and the fix — "the search matched nothing" vs "listings were found but could not be enriched" — with a verified quick-test pointer and a clear "empty results cost nothing" note. The run's status line also points to it, so API and agent callers see the diagnosis without opening Storage.
- **Empty-input runs name the field to fix.** A run started with an empty Zillow Search URL now fails with a `USER_MESSAGE` explaining exactly what to paste and where, instead of a bare error.
- **Failed runs get a real status screen.** The live status page now shows "Run stopped — nothing was saved" with the error text, instead of a stale in-progress view.
- **The free plan now says exactly what it held back.** When a search matches more properties than the free plan returns, the run reports the real number still waiting (or an honest "more matched — exact count not reported"), both in a `USER_MESSAGE` and as `heldBackByFreeCap` / `hadMoreBeyondCap` in `RUN_SUMMARY`. Nothing about the caps themselves changed.
- **Free plan: 15 runs per calendar month** (matches the parent actor; demo and failed runs don't count, the allowance resets on the 1st). The gate is graceful — the run succeeds, fetches nothing, charges nothing, and explains when the allowance resets.
- **Input form coaching** — the URL field now lists which URL shapes work (search, city browse, sold, single-property) and which don't (state-level, address-only), so the fix happens before the run instead of after.
- **README**: example-task links, expanded FAQ (zero-result causes, empty-run billing, AI-agent usage), lead-generation actors from the same author.

#### Fixed

- Paid onboarding no longer congratulates a failed run, and failed runs no longer consume an onboarding slot.
- The "Leave a review" link on the status page pointed at the parent actor's reviews — now points at this actor.
- `RUN_SUMMARY` could claim "returned the complete set" for a free run whose result list was clipped by the free cap — it now reports the clip truthfully.
- Stale plan-price figure on the status page corrected to the current $29/mo entry plan.

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

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

#### Added

- **Plain city URLs now work** — paste a Zillow city link such as `https://www.zillow.com/austin-tx/` or `https://www.zillow.com/austin-tx/houses/` and it's read 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 URLs are unaffected.

Same input shape, output columns, dataset shape, and pricing.

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

#### Fixed

- **Plain Zillow browse URLs now work** — for-sale browse URLs like `https://www.zillow.com/homes/Beverly-Hills,-CA_rb/` are now read as a location search (previously they completed with zero results). Recently-sold and `searchQueryState` URLs are unaffected.
- **Clearer message for URLs without search parameters** — if a URL can't be read as a Zillow search, the run now explains how to copy a working search URL instead of suggesting you widen your filters.

Same input shape, output columns, dataset shape, and pricing.

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

#### Fixed

- **Apartment-building rentals now emit useful data** — for ForRent URLs that return multi-unit apartment buildings (lat-long fallback identifier, `isBuilding: true`), the actor now emits a row directly from the search payload instead of pushing empty rows from a failed detail-enrichment call. `brokerName` = building name, plus address fields parsed from `p.address`, `price` from the lowest unit rent, `propertyDescription` summarising floorplans. New additive fields `availabilityCount` and `unitsAvailable`. Ported from parent zillow-scraper 2.3.69.

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

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

#### Changed

- **URL handling** — 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 (a `/homedetails/.../<zpid>_zpid/` URL — which this actor auto-detects). Added a tip when a `/homedetails/.../<zpid>_zpid/` URL is auto-converted, surfacing the details-URL shape as the shortest path for single-property lookups.
- **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 result set" and "we hit the cap, more available." Uses `maxProperties` (this actor's per-run cap). 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.
- **Input schema** — `zillowUrl` field description rewritten to explain the search-URL requirement (must contain `searchQueryState=`) and call out that single-address shortcuts (`/homes/<address>_rb/`) won't return listings.

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, Walk Score & photo gallery limits); 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

#### Changed

- Internal `processProperty` mapping brought in sync with parent zillow-scraper 2.3.52 + 2.3.53 (walk/transit/bike score key-name fix; photos endpoint envelope fix). No customer-visible change in this actor — `enrichWalkScore` and `enrichPhotos` toggles aren't exposed on this URL-only actor today (they're stripped at input validation with a notice pointing customers to the parent). The patches keep the spinoff code aligned with parent in case those toggles are ever surfaced here.

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

#### Changed

- Related actors section now lists the full Zillow family — `zillow-mcp-server` (MCP integration for Claude Desktop / Cursor / ChatGPT) added alongside the parent, `zillow-zip-search`, and this actor's existing rows.

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

#### Fixed

- Sold-listing URLs (`searchQueryState` URLs with `rs:true` filter, and `/homes/recently_sold/<Location>_rb/` URLs) returned empty datasets. Root cause: a sold search returns nothing unless a home type is set, even though a for-sale search works without one, and this actor was not setting a default. A default set of home types (single-family, townhouse, condo, apartment) is now applied to URL searches; filters embedded in `searchQueryState` continue to take priority.

#### Added

- `https://www.zillow.com/homes/recently_sold/<Location>_rb/` restored as a documented recipe in the README ("Shape 2 — Recently sold listings"). Validated end-to-end via prod smoke. The Shape 1 description now also explicitly mentions sold-listing coverage via the `rs:true` flag in `searchQueryState`.

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

#### Fixed

- README recipe section listed two URL shapes that returned empty datasets: bare location URLs (`https://www.zillow.com/homes/<Location>_rb/`) which the search rejected as "wrong format", and recently-sold URLs (`https://www.zillow.com/homes/recently_sold/<Location>_rb/`) which parse correctly but returned zero properties from the search. Both shapes removed from the README recipe section, the "What it does" overview, and the Programmatic / API curl example. Surviving recipes — `searchQueryState`-encoded search URLs and single-property `_zpid` pages — were validated end-to-end via prod smoke against build 0.0.3.

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

#### Removed

- `maxBudgetUsd` input field. Apify's built-in **"Maximum cost per run"** run option already provides per-run cost ceilings (Run options panel, identical semantics). Two overlapping mechanisms confused users — keeping only the platform-native one. Pasting `maxBudgetUsd` in input is now a soft `UNKNOWN_INPUT_KEYS` warning with a redirect to the Run option (no hard error). Free-tier `$1.20` cap continues to apply automatically — it's a code-side safeguard, not a user setting.

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

#### Fixed

- Default example URL now includes `searchQueryState` so the search accepts it on first trial. The 0.0.1 default (`/homes/Beverly-Hills,-CA_rb/`) was rejected by the search as "wrong format" — trial runs returned an empty dataset. The new default is read as a location search, which matches how customers paste URLs from Zillow's filter UI in practice.

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

#### Added

- Initial release of Zillow URL Search Property Scraper.
- Search Zillow listings by pasting any Zillow search URL — saved searches, city listings, sold listings, rentals with filters, single-property pages. Filters baked into the URL's `searchQueryState` (price, beds, baths, status, home type, days on Zillow, school rating, 50+ property features) are honored automatically.
- 74-column output dataset including agent contacts (name, phone, email), price history, Zestimate, school ratings, broker details, and property specs.
- 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).
- Free plan limits: 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) listing every URL / zpid skipped during the run with reason and category (`not_found`, `error`, `free_limit`, `test_run_cap`).
- Free-tier ceiling tracking (`FREE_LIMITS_APPLIED` KVS) — empty/omitted on paid runs.
- Onboarding banner (`USER_MESSAGE` KVS) shown to paid users on their 1st and 3rd paid run.
- Unknown-input-keys diagnostic (`UNKNOWN_INPUT_KEYS` KVS) — surfaces input field names that were silently dropped because they don't belong to this actor's schema (common when copy-pasting input from the multi-mode parent or the sibling ZIP-only actor).
- **Test-run cap on demo input.** Runs that leave the `zillowUrl` at the example value (`Beverly-Hills,-CA_rb`) cap output at 10 properties (~$0.80 max on FREE, ~$0.50 on DIAMOND), making "Try" runs predictable on any plan. The cap is restored to the normal plan limit (paid: unlimited; free: 15 properties / run) as soon as you change the URL.
