---
title: "Redfin API: Search Homes, Then Property and Valuation"
description: "Four Redfin endpoints at 1 credit each: find a region, search homes with a real JSON response, then call property and valuation by property_id."
url: https://perceptlayer.com/blog/redfin-api-property-valuation
---

[Blog](https://perceptlayer.com/blog) / [API guides](https://perceptlayer.com/blog/category/api-guides)

# Redfin API: Search Homes, Then Property and Valuation

15 Oct 2026 Perceptlayer 7 min read

Perceptlayer is a web data API, and its [Redfin API](https://perceptlayer.com/apis/redfin) has four GET endpoints: `locations`, `search`, `property` and `valuation`. `locations` returns the `region_id`, `region_type` and `market` that `search` needs, `search` returns homes with a `property_id`, and `property` and `valuation` take that ID. Every call costs 1 credit, a failed call costs nothing, and the free tier gives you 1,000 credits a month.

## Key takeaways

-   The flow is `/v1/redfin/locations` for `region_id`, `region_type` and `market`, `/v1/redfin/search` for homes, then `/v1/redfin/valuation` or `/v1/redfin/property` per `property_id`.
-   Each of the four endpoints costs 1 credit, so valuing 100 homes costs 101 credits plus the `search` calls that found them.
-   The recorded valuation for a listed Seattle home (property 124182) returned `"sectionPreviewText": "Estimate Not Available"`, so check that field before you build on a batch.
-   `region_type` codes in the recorded `locations` response: 1 neighborhood, 2 zip, 5 county, 6 city.
-   Free accounts run at 1 request a second; paying accounts run at least 5 a second, so batch time depends on your rate as well as your credits.

## What can you get from the Redfin API?

Perceptlayer's Redfin API has four GET endpoints, each costing 1 credit per successful call. The flow runs from finding a region, to listing homes in it, to detail or valuation for one home. Each endpoint returns named fields as JSON instead of a page of HTML.

| Endpoint | Returns | Credits | Required parameters |
| --- | --- | --- | --- |
| `GET /v1/redfin/locations` | Locations | 1 | `query` |
| `GET /v1/redfin/search` | Search | 1 | `region_id`, `region_type`, `market` |
| `GET /v1/redfin/property` | Property | 1 | `property_id` |
| `GET /v1/redfin/valuation` | Valuation | 1 | `property_id` |

`property` and `valuation` also accept an optional `listing_id`. Each endpoint has its own page with a playground: [Locations](https://perceptlayer.com/apis/redfin/locations), [Search](https://perceptlayer.com/apis/redfin/search), [Property](https://perceptlayer.com/apis/redfin/property) and [Valuation](https://perceptlayer.com/apis/redfin/valuation). The wider [real estate section](https://perceptlayer.com/verticals/real-estate) lists the other property sources in the catalogue.

## How do you authenticate and find a region?

Send your key in the `X-API-Key` header. Keys start with `sk_live_`, and you get one by verifying an email address at [signup](https://perceptlayer.com/signup), with 1,000 free credits every month and no credit card. If a header isn't possible, the `api_key` query parameter works too. The [authentication docs](https://docs.perceptlayer.com/authentication) cover both.

Start with `locations`. It takes one `query` string of up to 100 characters:

```bash
curl "https://api.perceptlayer.com/v1/redfin/locations?query=Seattle%2C+WA" \
  -H "X-API-Key: $API_KEY"
```

This is the recorded response, trimmed:

```json
{
  "data": {
    "locations": [
      {
        "name": "Seattle",
        "subName": "Seattle, WA, USA",
        "region_id": 16163,
        "region_type": 6,
        "region_type_name": "city",
        "market": "seattle",
        "url": "/city/16163/WA/Seattle"
      },
      {
        "name": "West Seattle",
        "region_id": 3040,
        "region_type": 1,
        "region_type_name": "neighborhood",
        "market": "seattle",
        …
      }
    ],
    "query": "Seattle, WA",
    "_usage": {
      "step": "Use region_id, region_type, and market from the locations response in your search query",
      "region_types": {
        "1": "neighborhood",
        "2": "zip",
        "5": "county",
        "6": "city"
      },
      …
    }
  }
}
```

The same query returns the city and its neighborhoods, each with its own `region_id`. Pick the row you want and pass its `region_id`, `region_type` and `market` to `search`.

## What do the region\_type codes mean?

`region_type` is an integer, and `search` accepts 1, 2, 4, 5 or 6. The recorded `locations` response lists four of them in `_usage.region_types` and repeats the name on each row as `region_type_name`. Rather than hard-code a code, read it from the row you picked.

| `region_type` | Name |
| --- | --- |
| 1 | neighborhood |
| 2 | zip |
| 5 | county |
| 6 | city |

Code 4 is accepted by `search`, but the recording doesn't show a name for it.

## Which parameters does the search endpoint take?

`search` requires `region_id` (integer), `region_type` (integer) and `market` (string, up to 30 characters), all three taken from a `locations` row. Everything else narrows the results. The [Search endpoint page](https://perceptlayer.com/apis/redfin/search) lets you try combinations in the playground before you write any code.

| Parameter | Type | Required |
| --- | --- | --- |
| `region_id` | integer | yes |
| `region_type` | integer | yes |
| `market` | string | yes |
| `min_price`, `max_price`, `num_beds`, `num_baths`, `property_types`, `status`, `sold_within_days`, `num_homes`, `page` | integer, except `num_baths` (number) and `property_types` (string) | no |

`status` accepts one of 1, 9, 130 or 131.

## What does a search response look like?

A recorded `/v1/redfin/search` response for Seattle ( `region_id=16163`, `region_type=6`, `sold_within_days=30`) returns `data.properties` with fields such as `property_id`, `listing_id`, `address`, `price`, `beds`, `baths`, `sqft` and `status`, plus a `count` of 350. Optional fields like `lot_size` appear only on some rows.

```bash
curl "https://api.perceptlayer.com/v1/redfin/search?region_id=16163&region_type=6&market=seattle&sold_within_days=30" \
  -H "X-API-Key: $API_KEY"
```

```json
{
  "data": {
    "properties": [
      {
        "property_id": 7716,
        "listing_id": 224554789,
        "address": "7700 E Green Lake Dr N Unit D4",
        "price": 885000,
        "status": "Coming Soon",
        …
      },
      {
        "property_id": 124182,
        "listing_id": 224635828,
        "address": "2517 25th Ave W",
        "city": "Seattle",
        "state": "WA",
        "zip": "98199",
        "price": 2750000,
        "beds": 3,
        "baths": 4,
        "sqft": 3570,
        "lot_size": 5120,
        "year_built": 2005,
        "status": "Coming Soon",
        …
      }
    ],
    "count": 350,
    "region_id": 16163,
    "region_type": 6
  }
}
```

Each row carries both `property_id` and `listing_id`, the identifiers that `property` and `valuation` take. Both rows show `"status": "Coming Soon"` even though the request passed `sold_within_days`, so read `status` on each row instead of assuming it from your filters. The first row has no `lot_size`, so treat optional fields as optional in your code.

## What does the valuation endpoint return?

The valuation endpoint returns a JSON object with the listing price, the last sold price and date, and an estimate summary in `sectionPreviewText`. For property 124182 in the recorded call, the estimate section read "Estimate Not Available". The valuation is for a home that is currently listed, and it came back without an estimate.

```bash
curl "https://api.perceptlayer.com/v1/redfin/valuation?property_id=124182&listing_id=224635828" \
  -H "X-API-Key: $API_KEY"
```

```json
{
  "data": {
    "numBeds": 3,
    "numBaths": 4,
    "sqFt": { "displayLevel": 1, "value": 3570 },
    "listingPrice": 2750000,
    "lastSoldPrice": 1050000,
    "lastSoldDate": 1285830000000,
    "priceInfo": { "amount": 2750000, "label": "Listed at Price", … },
    "sectionPreviewText": "Estimate Not Available",
    "propertyId": 124182
  }
}
```

What you do get is context: a `listingPrice` of 2,750,000 against a `lastSoldPrice` of 1,050,000. `lastSoldDate` looks like epoch milliseconds, which for 1285830000000 is 30 September 2010. What you don't get, for this home, is an estimate. That's a real limit if you plan to value a batch of listed homes: some rows may return a price history but no estimate, so count them instead of assuming every call yields a number.

Redfin explains how its estimates work on its [Redfin Estimate page](https://www.redfin.com/redfin-estimate), worth reading before you build anything that depends on a valuation.

## What does the property endpoint add?

`property` returns the detail record for one home. The recorded call for the same home returned `address`, `price`, `price_label` ("Listed at Price"), `beds`, `baths`, `sqft`, `lot_size`, `year_built`, `latitude`, `longitude` and a `photos` array of URLs, each call costing 1 credit.

```bash
curl "https://api.perceptlayer.com/v1/redfin/property?property_id=124182&listing_id=224635828" \
  -H "X-API-Key: $API_KEY"
```

If you only need price, beds and address, the search rows already have them. Call `property` when you need more than a search row holds, such as coordinates and photos, and `valuation` when the estimate or price history is the point. Keep the raw JSON from your own runs: data is collected from publicly available sources and returned as found at the time of the call, so treat a valuation as a snapshot.

## How do you value a batch of addresses in Python?

To value a batch, search once, collect each `property_id` and `listing_id`, then call `/v1/redfin/valuation` in a loop at no more than the account's request rate. On a 429 or 503 response, wait for the `Retry-After` seconds. The script below stores each response untouched and counts the homes that returned no estimate.

```python
import os
import time
import requests

BASE = "https://api.perceptlayer.com"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}

def get(path, **params):
    for _ in range(3):
        r = requests.get(BASE + path, headers=HEADERS, params=params, timeout=30)
        if r.status_code in (429, 503):
            time.sleep(int(r.headers.get("Retry-After", "1")))
            continue
        r.raise_for_status()
        print(path, "remaining:", r.headers.get("X-Credits-Remaining"))
        return r.json()
    raise RuntimeError(f"gave up on {path}")

search = get(
    "/v1/redfin/search",
    region_id=16163,
    region_type=6,
    market="seattle",
    sold_within_days=30,
)

valuations = {}
for home in search["data"]["properties"][:20]:
    valuations[home["property_id"]] = get(
        "/v1/redfin/valuation",
        property_id=home["property_id"],
        listing_id=home["listing_id"],
    )
    time.sleep(1.1)  # free accounts: 1 request a second

missing = [
    pid
    for pid, v in valuations.items()
    if v["data"].get("sectionPreviewText") == "Estimate Not Available"
]
print(len(missing), "of", len(valuations), "returned no estimate")
```

Two cautions. Requests have no idempotency key, so a call that timed out on your side may still have succeeded and been billed. And a plain retry loop is fine at 1 request a second, but on faster accounts read `RateLimit-Remaining`. The [rate limits docs](https://docs.perceptlayer.com/rate-limits) and the [errors docs](https://docs.perceptlayer.com/errors) cover both.

## What does valuing a batch cost?

Valuing homes through the Redfin API costs 1 credit per `valuation` call. Valuing 100 homes takes 1 `locations` call, N `search` calls and 100 `valuation` calls: 1 + N + 100 = 101 + N credits. In general, credits = calls × 1 credit and seconds = calls ÷ requests per second. Failed calls return `X-Credits-Used: 0`.

| Job | Calls | Credits |
| --- | --- | --- |
| Value 100 homes | 1 `locations` + N `search` + 100 `valuation` | 101 + N |
| Value 100 homes, plus details | the above + 100 `property` | 201 + N |
| Value 1,000 homes | 1 `locations` + N `search` + 1,000 `valuation` | 1,001 + N |

N is the number of `search` calls it takes to list your homes; check how many properties your own searches return. The 1,000-credit monthly free tier never covers the third row, since 1,001 + N is always more than 1,000. It covers the first row while N is 899 or less, and the second while N is 799 or less. Remember that a `valuation` call that returns "Estimate Not Available" still costs its credit.

Time matters too. As of 2026-10-24, free accounts get 1 request a second (60 a minute), so 1,000 valuations take 1,000 ÷ 1 = 1,000 seconds, about 17 minutes. Paying accounts run at least 5 requests a second, so the same batch takes 1,000 ÷ 5 = 200 seconds. The [credits docs](https://docs.perceptlayer.com/credits) explain how balances work, and [pricing](https://perceptlayer.com/pricing) shows what credits cost and the faster-rate options.

## When is another source a better fit?

If you want aggregate market statistics rather than individual homes, Redfin publishes downloadable market-level data on its own [Data Center](https://www.redfin.com/news/data-center/), which suits trend charts better than thousands of per-property calls.

For other countries, the catalogue has similar guides: [Immobilienscout24 for German listings](https://perceptlayer.com/blog/immobilienscout24-api-listings), [Rightmove for UK property](https://perceptlayer.com/blog/rightmove-api-property-data) and [Craigslist postings](https://perceptlayer.com/blog/craigslist-api-postings-json). More walkthroughs sit in the [API guides category](https://perceptlayer.com/blog/category/api-guides).

Your next step: [get a free API key](https://perceptlayer.com/signup), run `locations` for your own city, and feed one `property_id` and `listing_id` from the search into the valuation playground.

## APIs in this post

-   [Redfin **1 credit per call** · 4 endpoints](https://perceptlayer.com/apis/redfin)

## Frequently asked questions

### How much does the Redfin API cost per call?

Each of the four Redfin endpoints costs 1 credit per successful call. Failed calls cost nothing and return `X-Credits-Used: 0`. Every account gets 1,000 free credits a month after verifying an email, with no credit card. Purchased credits last 12 months. Pack sizes and what credits cost are on the [pricing page](https://perceptlayer.com/pricing).

### What do I need before calling the valuation endpoint?

You need a `property_id`, an integer. The easiest source is a row from a `search` response, where each home carries a `property_id` and a `listing_id`; `listing_id` is optional. Call `locations` first if you don't yet know which region to search, since it returns the `region_id`, `region_type` and `market` that `search` requires.

### Does the valuation endpoint always return an estimate?

No. The recorded valuation for a listed Seattle home (property 124182) returned `listingPrice`, `lastSoldPrice` and `lastSoldDate`, but its `sectionPreviewText` was "Estimate Not Available". Check that field on every response in a batch and keep the count of homes without an estimate.

### What happens when I hit the rate limit?

You get a `429` response with a `Retry-After` header giving the seconds to wait, and the body has the code `rate_limited`. Free accounts get 1 request a second. Limits are per account and shared by all keys. Wait the stated time and retry; a rate-limited call isn't billed. See [rate limits](https://docs.perceptlayer.com/rate-limits).

### Can an AI agent call these endpoints?

Yes. The MCP server at `https://api.perceptlayer.com/mcp` exposes `search_endpoints`, `get_endpoint` and `call_endpoint`. An agent can look up the Redfin endpoints for free, then spend 1 credit per successful call. The [AI agents docs](https://docs.perceptlayer.com/ai-agents) show how to add the server.

real estate redfin property valuation listings home search

## More from the blog

1.  [API guides](https://perceptlayer.com/blog/category/api-guides) 8 Oct 2026 Perceptlayer 6 min read
    
    ## [Realestate.com.au API: Australian Listings as JSON](https://perceptlayer.com/blog/realestate-com-au-api-listings)
    
    Search realestate.com.au by location and channel (buy, rent, sold), then open each listing by URL. Parameters, a recorded Sydney response and the cost.
    
2.  [API guides](https://perceptlayer.com/blog/category/api-guides) 6 Sept 2026 Perceptlayer 8 min read
    
    ## [Rightmove API: Get UK Property Listings and Sold Prices](https://perceptlayer.com/blog/rightmove-api-property-data)
    
    Pull Rightmove UK listings, sold prices and agents as JSON with 8 endpoints at 1 credit per call, with a real London search response and cURL examples.
    
3.  [API guides](https://perceptlayer.com/blog/category/api-guides) 11 Aug 2026 Perceptlayer 7 min read
    
    ## [Domain.com.au API: Australian Listings and Suburb Data](https://perceptlayer.com/blog/domain-com-au-api-listings)
    
    Call /v1/domain-com-au/search for Australian listings, then property, auction results and suburb insights as JSON. Parameters, a real response, 1 credit a call.
