List residential properties sold in a ZIP in the last 365 days

GET /api/properties/sold/by-zip/

1 credit per 20 properties

What it returns

Every residential property sold in a given US ZIP code within the last 365 days, with sale date, sale price, coordinates, and basic property characteristics (bed/bath, square footage, year built, lot size). Sourced from the residential_sold collection — a deduplicated rollup of MLS sold records refreshed on demand when the per-ZIP cache is older than 4 hours.

When to use it

Date range

By default the endpoint returns the full trailing 365 days. Pass start_date, end_date, or both (YYYY-MM-DD) to narrow that to a specific window — for example one calendar month at a time instead of re-pulling the whole year on every poll:

Both bounds are optional and inclusive, and both are independent: pass only start_date for an open-ended window, or only end_date to cut off recent sales. Passing neither leaves existing behaviour unchanged.

Either bound must fall within the last 365 days. An older date returns 400 naming the earliest date we can serve, rather than quietly returning a partial set.

Property type

Pass property_type to keep only the types you model. One value or a comma-separated list, matched against the same property_type field each row returns:

Omitting it returns every type, exactly as before. An unknown value returns 400 listing the accepted values rather than an empty result.

Pricing

1 credit per 20 properties returned, rounded up. A request that returns 100 properties costs 5 credits. Use the limit parameter to cap the cost — a limit=20 always costs exactly 1 credit. Charged only on 200; 402/400/5xx cost nothing.

Errors

StatusMeaning
400Missing zip parameter, non-integer limit, a malformed / out-of-window start_date or end_date, or an unknown property_type.
401Authentication failed or account missing.
402No subscription, or insufficient credits for the property count this ZIP would return. The error body includes the credit estimate so you can lower limit and retry.
503Upstream datastore or refresh error. Safe to retry.

FAQ

How fresh is the data?

The per-ZIP cache refreshes when stale (older than 4 hours) on demand. A first request to a cold ZIP may take longer while the refresh runs; subsequent requests within the 4-hour window hit cache.

Why do some properties have sold_price: null?

The MLS suppresses price on private sales, off-market transfers, and some agent-sale records. The property still appears (it sold), but the price field is null. Filter on your side if you need price-bearing records only.

What counts as "residential"?

Everything the sold feed files as residential: single-family, condos, townhomes, multi-family, apartments, mobile homes, plus a small tail of other types. Each row's property_type says which, and the property_type filter takes the same values. Commercial and land-only records are rare here — they live in other collections.

Why is dom sometimes null?

Days-on-market requires listing-history dates that older records may not carry. For records that lack dom natively, we compute it best-effort from list_date to sold_date; when neither path resolves, the field is null.

Parameters

Responses

More in Market Data