# Zillow Home Value Index Scraper (`automation-lab/zillow-zhvi-regional-time-series`) Actor

Export official Zillow Home Value Index monthly observations for US metros and the country. Filter exact regions and dates with source provenance.

- **URL**: https://apify.com/automation-lab/zillow-zhvi-regional-time-series.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.44 / 1,000 item extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Zillow Home Value Index Scraper

Export the official **Zillow home value index** as monthly region/date/value observations for recurring housing-market benchmarking. Compare US metropolitan areas and the national series without extracting individual properties. The fixed dataset is middle-tier, all-home (single-family and condo), smoothed and seasonally adjusted ZHVI.

### Who is it for?

Housing analysts, investment researchers and data teams can refresh dated regional series for dashboards, historical comparisons and residential-market research. This is an index export, not an individual home's Zestimate or an investment recommendation.

### Why use this Actor?

Turn Zillow's wide CSV into tidy-long numeric rows. Exact region filters and inclusive dates select observations, while every row retains official source provenance and the newest source month. No account, browser, proxy or external paid data subscription is required.

### Getting started

1. Select region IDs or exact names; omit both for all available regions.
2. Optionally restrict dates and region type.
3. Set a global observation cap.
4. Run and download the dataset as JSON, CSV or Excel using Apify's exports.

```json
{"regionIds":[102001],"startDate":"2026-01-01","maxItems":25}
```

The national series uses RegionID 102001. Metros use names such as `New York, NY`. Names must match the entire source name; `New York` alone does not match that metro.

### Zillow home value index coverage

Only the official Metro/country `Metro_zhvi_uc_sfrcondo_tier_0.33_0.67_sm_sa_month.csv` is supported. The source currently includes 895 regions and monthly history from 2000; individual region coverage can start later. Source availability and dates can change. No ZIP, city, county, state-level series, rent indices, mortgage rates or listings are included.

### Inputs

| Field | Behavior |
|---|---|
| regionIds | Positive integer IDs; ANY ID matches exactly. |
| regionNames | ANY whole name matches, case-insensitive, trimmed. Mutually exclusive with regionIds. |
| regionType | all (default), country, or msa (metro). Applies with either filter. |
| startDate | Inclusive YYYY-MM-DD lower bound. Omit for earliest history. |
| endDate | Inclusive YYYY-MM-DD upper bound. Omit for latest history. |
| maxItems | 1–10000 observations globally; default 1000. Zero/unlimited not supported. |

Unknown input fields and malformed/conflicting filters fail. Results follow source region order and ascending dates within each region. The cap is applied after filtering and deduplication, not per region. A platform billing cap can stop earlier. For complete large histories, split runs by explicit regions and date ranges.

### Output

One row represents one nonmissing monthly observation. Missing values are omitted, not converted to zero. Duplicate region/date pairs are removed.

| Field | Meaning |
|---|---|
| regionId, regionName, regionType | Official region identity and country/msa type. |
| stateName | Source state abbreviation; null for country or unavailable. |
| sizeRank | Zillow's region size rank, not a value ranking. |
| date | Monthly source observation date. |
| value, currency | Numeric ZHVI in USD. |
| metric | Exact fixed series identifier. |
| sourceUrl | Official Zillow CSV. |
| sourceLatestDate | Newest source date column; not the selected row date. |
| scrapedAt | UTC fetch time, not a source publication time. |

Example from the official national series:

```json
{
  "regionId": 102001,
  "regionName": "United States",
  "regionType": "country",
  "stateName": null,
  "sizeRank": 0,
  "date": "2026-08-31",
  "value": 368696.68474913173,
  "currency": "USD",
  "metric": "zhvi_uc_sfrcondo_tier_0.33_0.67_sm_sa",
  "sourceUrl": "https://files.zillowstatic.com/research/public_csvs/zhvi/Metro_zhvi_uc_sfrcondo_tier_0.33_0.67_sm_sa_month.csv",
  "sourceLatestDate": "2026-08-31",
  "scrapedAt": "2026-10-12T14:00:00.000Z"
}
```

The fetch timestamp above is illustrative. Values and history can be revised by Zillow between runs.

### How much does it cost to export Zillow home value index observations?

Pay-per-event billing includes one `start` fee of $0.0025 per run and one `item` event per saved observation. Rejected, missing and duplicate observations incur no item fee.

| Spend tier | Price per observation |
|---|---:|
| FREE | $0.00276 |
| BRONZE | $0.0024 |
| SILVER | $0.001872 |
| GOLD / PLATINUM / DIAMOND | $0.00144 |

At BRONZE, 10 observations cost about $0.0265, 100 about $0.2425 and 1000 about $2.4025, including the start fee. These are estimates, not guaranteed invoices; refer to the pricing panel for your active tier. Spend tiers follow aggregate monthly Store spending, not a private per-Actor volume schedule.

### Integrations

Schedule a recurring Apify run with explicit region IDs and recent dates, then send its dataset to a spreadsheet or warehouse. Join by regionId/date/metric, and upsert observations because historical values can change. Use sourceLatestDate to distinguish an unchanged source release from a new month. Scheduling and revision comparison happen in your downstream workflow; this Actor does not send alerts or maintain cross-run change state.

### API usage

Start asynchronously, retain the returned run ID, follow that same run until terminal, and read its default dataset after success.

```bash
curl -X POST "https://api.apify.com/v2/acts/automation-lab~zillow-zhvi-regional-time-series/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" -H 'Content-Type: application/json' \
  -d '{"regionIds":[102001],"startDate":"2026-01-01","maxItems":25}'
```

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/zillow-zhvi-regional-time-series')
  .call({ regionIds: [102001], startDate: '2026-01-01', maxItems: 25 });
console.log((await client.dataset(run.defaultDatasetId).listItems({ limit: 25 })).items);
```

```python
from apify_client import ApifyClient
import os
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/zillow-zhvi-regional-time-series').call(
    run_input={'regionIds': [102001], 'startDate': '2026-01-01', 'maxItems': 25})
print(client.dataset(run['defaultDatasetId']).list_items(limit=25).items)
```

### MCP

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/zillow-zhvi-regional-time-series"
```

Claude Desktop, Cursor and VS Code: use the equivalent HTTP-client configuration (client transport support may vary):

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/zillow-zhvi-regional-time-series"}}}
```

Configure Apify authentication according to your client. Discover actual names and schemas with `tools/list`; the selected Actor also adds run and storage helpers. Discovery does not authorize execution.

Example prompts: “Export US national ZHVI since January 2026, at most 25 observations.” Or “Extract the New York, NY monthly index for 2025, limited to 12 rows.” Start once with `call-actor` using a selected `waitSecs` of 30 (allowed 0–45 seconds; default 30). Configure the client's request timeout to 45 seconds, above that server wait plus transport margin, within a total 120-second deadline. Retain the returned run ID, status and storage IDs; these are metadata, not observations. If nonterminal, use `get-actor-run` for that same run with bounded backoff (2, 4, 8 seconds, capped at 10), stopping at the total deadline. At deadline report pending and its run ID, not a fabricated result. Recover known runs after transport timeouts rather than starting again; if the run ID is unknown, report uncertainty instead of blindly rerunning.

After success, use `get-dataset-items` with the returned `defaultDatasetId` and explicit `limit: 20`, `offset: 0`, and needed `fields` (for example `regionId,regionName,date,value,currency,metric,sourceUrl,sourceLatestDate`), in the argument format discovered by `tools/list`. Read untransformed JSON pages, advancing the source offset according to pagination metadata, not transformed row counts. Stop at source exhaustion or a total consumer budget of 100 source rows and 64 KiB serialized UTF-8 result content admitted to model context, whichever comes first. Process pages and enforce bytes host-side before model injection; omit or summarize oversized rows/pages with disclosure. If the client cannot intercept responses, do not claim a hard byte guarantee. Report returned rows, the continuation offset and partial/truncated status when incomplete; full exports remain in storage or downstream processing outside model context. Failed runs may have partial data, not a successful complete result. These consumer context limits do not reduce Actor collection scope or output fields.

### Reliability and limitations

The fixed public CSV is fetched once per run, with at most three attempts for network timeouts, HTTP 429 or temporary server errors. Deterministic failures and malformed source data fail visibly. No proxy fallback is enabled. An unmatched region or date range returns an empty successful dataset; inspect your exact filter and available source dates. Data is monthly and revised, not real-time.

### Data handling, AI and responsible use

No AI is used in runtime extraction or output. Data consists of public regional housing statistics, not personal property records. Filters and summary are stored in the run's input/KV store; results and logs use your Apify storage retention settings. The Actor does not maintain global caches or sessions. Delete run storage through Apify when no longer needed.

Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL queries are removed; reports are retained for 30 days. No diagnostic credentials are public inputs. Apify hosts runtime and storage; Zillow provides the public export.

### Legality and attribution

Use Zillow Research attribution and review source terms and methodology for your intended redistribution/use. This independent tool is not affiliated with or endorsed by Zillow. It uses Apify's standard user terms and does not grant additional rights to source data.

### FAQ and troubleshooting

**Is this a home's Zestimate?** No: it is a regional index series, not a property estimate.

**Why are some months absent?** Blank source cells are omitted; coverage varies by region. No interpolation is performed.

**Why did my recent dates return nothing?** The current export may end before your date range. Check sourceLatestDate from an unfiltered date control.

**How do I get complete history for all regions?** Partition by region/date; each run caps accepted observations globally at 10000. A run at the cap is not evidence of source exhaustion.

**Where can I report a problem?** Open an Apify Store issue with your input and run link; never include credentials.

### Related Actors

For individual property/listing data rather than regional indices, see [Zillow Scraper](https://apify.com/automation-lab/zillow-scraper). This Actor remains a separate official monthly-series workflow.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/zillow-zhvi-regional-time-series/changelog.md

# Actor input Schema

## `regionIds` (type: `array`):

Exact positive Zillow RegionID values. ANY ID matches; mutually exclusive with regionNames. Omit both to include all regions allowed by regionType.

## `regionNames` (type: `array`):

Case-insensitive exact whole-name match after trimming whitespace. ANY name matches. Use Zillow names such as United States or New York, NY; no substring matching. Mutually exclusive with regionIds.

## `regionType` (type: `string`):

Restricts the fixed Metro/country CSV. msa means metropolitan statistical area; ZIP, city, county and state datasets are not supported.

## `startDate` (type: `string`):

Valid YYYY-MM-DD lower bound on monthly observation dates. Omit for earliest available date. Must not exceed endDate.

## `endDate` (type: `string`):

Valid YYYY-MM-DD upper bound on monthly observation dates. Omit for latest source date. Future ranges can return no observations.

## `maxItems` (type: `integer`):

Global run cap of accepted nonmissing region/date/value observations after all filters and deduplication. Source region order then oldest-to-newest dates. 1–10000; zero/unlimited not supported. Platform billing cap can stop earlier.

## Actor input object example

```json
{
  "regionIds": [
    102001
  ],
  "regionType": "all",
  "startDate": "2026-01-01",
  "maxItems": 20
}
```

# Actor output Schema

## `overview` (type: `string`):

Saved nonmissing region/date/value observations in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "regionIds": [
        102001
    ],
    "startDate": "2026-01-01",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/zillow-zhvi-regional-time-series").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "regionIds": [102001],
    "startDate": "2026-01-01",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/zillow-zhvi-regional-time-series").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "regionIds": [
    102001
  ],
  "startDate": "2026-01-01",
  "maxItems": 20
}' |
apify call automation-lab/zillow-zhvi-regional-time-series --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/zillow-zhvi-regional-time-series"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/9AteZGtHws22VYoFc/builds/gGmCW6DF9fvhsFqhJ/openapi.json
