Datasets API endpoint
Use Crawlora's US Housing Markets Dataset Search API to search or inspect stored structured datasets as JSON. This page includes request parameters, cURL examples, response schema, validation behavior, credit cost, and a Playground link for testing before integration. Dataset endpoints read indexed records and do not apply proxy routing.
/datasets/housing-markets/searchSearches monthly Redfin housing-market statistics per region and property type since 2012, joined to Census ACS income for affordability metrics. region_type enum: `national`, `metro`, `county`, `city`, `zip`. property_type enum: `All Residential`, `Single Family Residential`, `Condo/Co-op`, `Townhouse`, `Multi-Family (2-4 Unit)`, `Single Units Only`. Sort enum: `relevance`, `price_desc`, `price_asc`, `list_price_desc`, `list_price_asc`, `price_to_income_desc`, `price_to_income_asc`, `salary_to_buy_desc`, `salary_to_buy_asc`, `dom_asc`, `dom_desc`, `inventory_desc`, `homes_sold_desc`, `period_desc`. Use `latest=true` for the most recent period per region series. Developers commonly use this endpoint for repeatable dataset search, filtering, facets, local business enrichment, analytics, exports, and internal tools that need structured records beyond the limited manual refinement available in the Google Maps app. Authentication uses the x-api-key header, usage is metered with the credit cost shown on this page, and the request does not trigger live scraping or proxy routing.
Request parameters are generated from the active endpoint catalog. Dataset parameters filter, page, facet, or locate stored structured records; they do not configure a live scraper or proxy path.
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| q | string | No | Full-text query over region name and city, max 256 characters | ||
| region_type | string | No | Region level enum: national, metro, county, city, zip | ||
| state_code | string | No | Exact two-letter state code filter, e.g. CA | ||
| property_type | string | No | Property type enum: All Residential, Single Family Residential, Condo/Co-op, Townhouse, Multi-Family (2-4 Unit), Single Units Only | ||
| parent_metro_code | string | No | Exact parent metro (CBSA) code filter, e.g. 16980 | ||
| zip_code | string | No | Exact zip code filter (zip-level rows only), e.g. 60616 | ||
| period | string | No | Exact period start date filter, YYYY-MM-DD | ||
| latest | boolean | No | Filter for the most recent period per region and property type | ||
| min_median_sale_price | number | No | Minimum median sale price in USD | ||
| max_median_sale_price | number | No | Maximum median sale price in USD | ||
| min_median_list_price | number | No | Minimum median list price in USD | ||
| max_median_list_price | number | No | Maximum median list price in USD | ||
| min_price_to_income | number | No | Minimum price-to-income ratio | ||
| max_price_to_income | number | No | Maximum price-to-income ratio | ||
| min_salary_to_buy | integer | No | Minimum salary needed to buy in USD per year | ||
| max_salary_to_buy | integer | No | Maximum salary needed to buy in USD per year | ||
| min_median_dom | number | No | Minimum median days on market | ||
| max_median_dom | number | No | Maximum median days on market | ||
| min_inventory | integer | No | Minimum active inventory | ||
| max_inventory | integer | No | Maximum active inventory | ||
| min_homes_sold | integer | No | Minimum homes sold in the period | ||
| sort | string | No | Sort enum: relevance, price_desc, price_asc, list_price_desc, list_price_asc, price_to_income_desc, price_to_income_asc, salary_to_buy_desc, salary_to_buy_asc, dom_asc, dom_desc, inventory_desc, homes_sold_desc, period_desc | ||
| page | integer | No | 1 | Page number, defaults to 1 | |
| page_size | integer | No | 20 and maxes at 100 | Page size, defaults to 20 and maxes at 100; page * page_size must be <= 10000 | |
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/datasets/housing-markets/search?q=coffee&latest=true&page=1" \ -H "x-api-key: $CRAWLORA_API_KEY"
Send your scraping API key in the x-api-key header. Use the console API Keys page to rotate or select the active key.
Endpoint usage is metered in credits. The plan prices, included credits, limits, and overage rates below match the active backend billing configuration.
| Plan | Price | Included credits | Daily cap | Rate limit | Overage |
|---|---|---|---|---|---|
| Free | $0/mo | 2,000 | 500 daily credits | 5/min | No overage |
| Starter | $9/mo | 20,000 | 5,000 daily credits | 15/min | $0.75/1,000 overage credits when enabled |
| Growth | $29/mo | 100,000 | 25,000 daily credits | 45/min | $0.45/1,000 overage credits when enabled |
| Pro | $79/mo | 400,000 | No daily cap | 120/min | $0.30/1,000 overage credits |
| Business | $199/mo | 1,200,000 | No daily cap | 300/min | $0.20/1,000 overage credits |
| Enterprise | $499/mo | 5,000,000 | No daily cap | 1,000/min | $0.12/1,000 overage credits |
This endpoint reads stored indexed dataset records. It does not execute a live upstream Google Maps request, browser session, or proxy-routed scraping job.
- One record per region x month x property type; `is_latest` marks each series' most recent month — combine `latest=true` with `region_type` for current-market rankings. - MoM/YoY change fields (`median_sale_price_yoy` etc.) are fractions as published by Redfin (`0.05` = +5%). - Affordability fields (`median_household_income`, `price_to_income`, `salary_to_buy`, `affordability_gap`) exist only where the Census income geography matched and a median sale price is present; `salary_to_buy` assumes 20% down, a 30-year fixed mortgage at `mortgage_rate_pct`, 1.5%/yr taxes+insurance, and a 28% payment-to-income ratio. - `income_vintage` is `acs2024_5yr`; ACS incomes lag current prices by ~2 years. - Defaults to `relevance` sort with `q`, `price_to_income_desc` with `latest=true`, otherwise `period_desc`. - Missing metrics are `null`, never `0` — Redfin leaves thin-market cells empty. - The maximum result window is `10000`; `page * page_size` must not exceed `10000`. - Invalid enum values return the standard invalid params envelope. - Returns an empty `items` array (not an error) when the dataset has no matches yet. - Does not trigger live scraping. Example response: ```json { "code": 200, "msg": "OK", "data": { "dataset": "housing-markets", "items": [ { "region_type": "metro", "region_type_id": -2, "table_id": 41940, "region": "San Jose, CA metro area", "state_code": "CA", "property_type": "All Residential", "property_type_id": -1, "period_begin": "2026-05-01", "period_end": "2026-05-31", "is_latest": true, "median_sale_price": 1650000, "median_sale_price_yoy": 0.041, "median_list_price": 1498000, "homes_sold": 812, "inventory": 1421, "median_dom": 12, "median_household_income": 153202, "income_geo_id": "0400000US06", "income_vintage": "acs2024_5yr", "price_to_income": 10.77, "salary_to_buy": 322403, "affordability_gap": 169201, "mortgage_rate_pct": 6.49, "source": "redfin_data_center", "run_id": "housing-20260711", "schema_version": 1 } ], "page": 1, "page_size": 20, "total": 934, "sort": "price_to_income_desc" } } ```
Crawlora does not silently return invalid dataset search results when filters, pagination, coordinates, or stored record lookups cannot be satisfied.
| Status | Common failure case |
|---|---|
| 400 | Invalid input, missing required parameter, invalid enum, bad coordinate pair, or result window beyond the dataset limit |
| 404 | Requested stored dataset item is not present |
| 429 | Plan or endpoint rate limit exceeded |
| 500 | Internal dataset query or storage error |
When possible, Crawlora returns structured error context so your integration can adjust filters, page size, location inputs, or lookup identifiers.
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/definitions/app.Response |
| 429 | Too Many Requests | #/definitions/app.Response |
| 500 | Internal Server Error | #/definitions/app.Response |
{
"code": 200,
"msg": "OK",
"data": {
"dataset": "housing-markets",
"items": [
{
"region_type": "metro",
"region_type_id": -2,
"table_id": 41940,
"region": "San Jose, CA metro area",
"state_code": "CA",
"property_type": "All Residential",
"property_type_id": -1,
"period_begin": "2026-05-01",
"period_end": "2026-05-31",
"is_latest": true,
"median_sale_price": 1650000,
"median_sale_price_yoy": 0.041,
"median_list_price": 1498000,
"homes_sold": 812,
"inventory": 1421,
"median_dom": 12,
"median_household_income": 153202,
"income_geo_id": "0400000US06",
"income_vintage": "acs2024_5yr",
"price_to_income": 10.77,
"salary_to_buy": 322403,
"affordability_gap": 169201,
"mortgage_rate_pct": 6.49,
"source": "redfin_data_center",
"run_id": "housing-20260711",
"schema_version": 1
}
],
"page": 1,
"page_size": 20,
"total": 934,
"sort": "price_to_income_desc"
}
}Request schema
No body schema
Response schema
#/definitions/datasets.housingMarketsSearchResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | datasets.HousingSearchResponse | No | ||||
| data.dataset | string | No | ||||
| data.items | array | No | ||||
| data.items[].affordability_gap | integer | No | ||||
| data.items[].avg_sale_to_list | number | No | ||||
| data.items[].city | string | No | ||||
| data.items[].homes_sold | integer | No | ||||
| data.items[].income_geo_id | string | No | ||||
| data.items[].income_vintage | string | No | ||||
| data.items[].inventory | integer | No | ||||
| data.items[].is_latest | boolean | No | IsLatest is true only on the most recent period per (region_type_id, table_id, property_type_id); the loader maintains it. | |||
| data.items[].last_updated | string | No | ||||
| data.items[].list_price_to_income | number | No | ||||
| data.items[].loaded_at | string | No | ||||
| data.items[].median_dom | number | No | ||||
| data.items[].median_household_income | integer | No | Affordability join (Census ACS 5-year median household income). Present only where the income geography matched and median_sale_price exists. | |||
| data.items[].median_list_ppsf | number | No | ||||
| data.items[].median_list_ppsf_mom | number | No | ||||
| data.items[].median_list_ppsf_yoy | number | No | ||||
| data.items[].median_list_price | number | No | ||||
| data.items[].median_list_price_mom | number | No | ||||
| data.items[].median_list_price_yoy | number | No | ||||
| data.items[].median_ppsf | number | No | ||||
| data.items[].median_ppsf_mom | number | No | ||||
| data.items[].median_ppsf_yoy | number | No | ||||
| data.items[].median_sale_price | number | No | ||||
| data.items[].median_sale_price_mom | number | No | ||||
| data.items[].median_sale_price_yoy | number | No | ||||
| data.items[].months_of_supply | number | No | ||||
| data.items[].mortgage_rate_pct | number | No | ||||
| data.items[].new_listings | integer | No | ||||
| data.items[].off_market_in_two_weeks | number | No | ||||
| data.items[].parent_metro | string | No | ||||
| data.items[].parent_metro_code | string | No | ||||
| data.items[].pending_sales | integer | No | ||||
| data.items[].period_begin | string | No | ||||
| data.items[].period_end | string | No | ||||
| data.items[].price_drops | number | No | ||||
| data.items[].price_to_income | number | No | ||||
| data.items[].property_type | string | No | ||||
| data.items[].property_type_id | integer | No | ||||
| data.items[].region | string | No | ||||
| data.items[].region_type | string | No | RegionType is the normalized region level: national, metro, county, city, zip. | |||
| data.items[].region_type_id | integer | No | ||||
| data.items[].run_id | string | No | ||||
| data.items[].salary_to_buy | integer | No | ||||
| data.items[].schema_version | integer | No | ||||
| data.items[].sold_above_list | number | No | ||||
| data.items[].source | string | No | ||||
| data.items[].state | string | No | ||||
| data.items[].state_code | string | No | ||||
| data.items[].table_id | integer | No | ||||
| data.items[].zip_code | string | No | ZipCode is set on zip rows only, parsed from REGION ("Zip Code: 60616"). | |||
| data.page | integer | No | ||||
| data.page_size | integer | No | ||||
| data.sort | string | No | ||||
| data.total | integer | No | ||||
| msg | string | No | OK |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/datasets/housing-markets/search?q=coffee&latest=true&page=1" \
-H "x-api-key: $CRAWLORA_API_KEY"Crawlora is designed for responsible structured public web data workflows. Customers are responsible for using Crawlora in compliance with applicable laws, third-party rights, target-platform rules, and Crawlora terms.
Read Crawlora terms