# Distressed Property Lead Scraper - Probate & Foreclosure (`parsebird/distressed-property-scraper`) Actor

Scrape probate, foreclosure, sheriff sale, tax lien, and tax sale leads from US county and state open-data portals. Normalized fields: case number, owner/defendant name, address, sale date, equity estimate.

- **URL**: https://apify.com/parsebird/distressed-property-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.79 / 1,000 record scrapeds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### Distressed Property Lead Scraper - Probate & Foreclosure

Scrape probate, foreclosure, sheriff sale, tax lien, and tax sale leads straight from US county and state government open-data portals — no login, scraping challenges, or CAPTCHAs involved, because it's all public data served through official APIs.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Queries 24 verified Socrata open-data portals across 12 states, classifies matching datasets by event type, and normalizes every row into one 30-field schema — case number, owner/defendant name, property address, sale date, and an estimated-equity calculation when the source publishes both value and mortgage figures.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```
parsebird/distressed-property-scraper on Apify. Call: ApifyClient("TOKEN").actor("parsebird/distressed-property-scraper").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items for results. Key inputs: eventTypes (array, default [] = all, one or more of "probate"/"foreclosure"/"sheriff_sale"/"tax_lien"/"tax_sale"), states (array of US two-letter codes, default [] = all covered states), counties (array of county names e.g. "King"/"Cook"/"Orleans", case-insensitive, default [] = all), dateFrom/dateTo (ISO "YYYY-MM-DD", filters sale_date or filing_date), minEstimatedEquity (integer USD, 0 = off), onlyOwnerOccupied (boolean, default false), maxItems (integer, default 100). Output fields: event_id, event_type, source_url, dataset_name, domain, county, state, filing_date, sale_date, case_number, decedent_name, executor_name, attorney_name, defendant_name, plaintiff_name, property_address, parcel_apn, property_type, estimated_value_usd, mortgage_balance_usd, lien_amount_usd, opening_bid_usd, winning_bid_usd, owner_occupied, property_equity_estimate_usd, status, lat, lng, raw_source_fields (original row, JSON-encoded). Full actor spec: fetch build via GET https://api.apify.com/v2/acts/parsebird~distressed-property-scraper (Bearer TOKEN). Get token: https://console.apify.com/account/integrations
```

### What does Distressed Property Lead Scraper do?

This Actor queries the [Socrata open-data network](https://dev.socrata.com/) — the same backend used by [data.cityofnewyork.us](https://data.cityofnewyork.us/), [data.nola.gov](https://data.nola.gov/), [datacatalog.cookcountyil.gov](https://datacatalog.cookcountyil.gov/), and dozens of other county and state portals. It searches a curated, verified list of 24 of these portals for datasets matching your requested event type(s), pages through each match, and normalizes the wildly heterogeneous source columns (`cdccasenumber`, `propertyaddress`, `house_number` + `street_name`, `physadd`, `block` + `lot`, and more) into one consistent schema.

- 📍 **24 verified portals across 12 states** — LA, WA, MD, CT, IL, MA, CO, CA, NY, NJ, OR, PA, TX
- 🏛️ **5 event types** — probate, foreclosure, sheriff sale, tax lien, tax sale
- 🧩 **Column normalization** — case numbers, party names, addresses, parcel IDs, and dollar amounts get mapped to one schema regardless of how each source portal names them
- 💰 **Equity estimation** — when a source publishes both an assessed value and a mortgage balance, `property_equity_estimate_usd` is calculated automatically
- 🔎 **Precision-filtered** — administrative/procedural datasets that merely mention an event type (lender exemption affidavits, grant-award lists, election results) are excluded; so are aggregate statistics tables that have no identifying case or property behind each row
- ⏱️ **Scheduling** — run this Actor daily or weekly via Apify Scheduler to catch newly filed cases as county portals update
- 🔌 **API access** — trigger runs and pull results programmatically via the Apify API or client libraries
- 🔗 **Integrations** — connect to Google Sheets, Zapier, Make, Slack, and webhooks without writing code
- 📊 **Flexible export** — download results as JSON, CSV, or Excel, or query them via API

### What data can you extract?

| Field | Description |
|-------|-------------|
| `event_type` | probate, foreclosure, sheriff\_sale, tax\_lien, or tax\_sale |
| `state` / `county` | US state code; county name when the portal is county-scoped, `null` for city/state-level portals |
| `case_number` | Court case or docket number |
| `defendant_name` / `plaintiff_name` | Defendant/debtor/owner and plaintiff/creditor/lender, when the source labels them |
| `decedent_name` / `executor_name` / `attorney_name` | Probate-specific party names |
| `property_address` / `parcel_apn` | Street address and assessor parcel number, assembled from split columns when needed |
| `filing_date` / `sale_date` | Filing/recording/notice date and scheduled or completed sale date |
| `estimated_value_usd` / `mortgage_balance_usd` / `property_equity_estimate_usd` | Assessed value, outstanding mortgage, and the calculated equity gap (only when the source publishes both figures) |
| `opening_bid_usd` / `winning_bid_usd` | Auction bid amounts |
| `owner_occupied` | `true`/`false` when the source marks homestead/owner-occupancy status |
| `raw_source_fields` | The original source row, JSON-encoded, so nothing the source publishes is ever lost |

Field population depends entirely on what each source portal publishes — a NYC tax lien list and a Louisiana sheriff sale record don't share the same columns. `raw_source_fields` always preserves the original row for anything the unified schema doesn't cover.

### Input parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `eventTypes` | array | `[]` (all) | One or more of `probate`, `foreclosure`, `sheriff_sale`, `tax_lien`, `tax_sale` |
| `states` | array | `[]` (all) | US two-letter state codes. Filters source portals by geographic scope |
| `counties` | array | `[]` (all) | County names, e.g. `King`, `Cook`, `Orleans`. Case-insensitive |
| `dateFrom` / `dateTo` | string | `""` | ISO date (`YYYY-MM-DD`). Keeps records with a `sale_date` or `filing_date` in range |
| `minEstimatedEquity` | integer | `0` | Drops records where `estimated_value_usd − mortgage_balance_usd` is below this USD amount. `0` disables the filter |
| `onlyOwnerOccupied` | boolean | `false` | Drops records where owner-occupancy can't be verified `true` from the source |
| `maxItems` | integer | `100` | Hard cap on records returned, counted across all datasets |
| `proxyConfiguration` | object | Apify proxy off | Socrata endpoints are open, unauthenticated APIs — proxies aren't needed. Leave the default |

### Output example

```json
{
  "event_id": "data.nola.gov:d52w-8nva:2012-5883",
  "event_type": "sheriff_sale",
  "source_url": "https://data.nola.gov/d/d52w-8nva",
  "dataset_name": "Sheriff Sales - Lien Foreclosures",
  "domain": "data.nola.gov",
  "county": "Orleans",
  "state": "LA",
  "filing_date": null,
  "sale_date": null,
  "case_number": "2012-5883",
  "decedent_name": null,
  "executor_name": null,
  "attorney_name": null,
  "defendant_name": "GREGORY DELORIMIER/ MILDRED C DELORIMIER / KIM DELORIMIER/ GAIL C GILBERT/ DEBORAH ZANCA/ MICHAEL DELORIMIER",
  "plaintiff_name": "CITY OF NEW ORLEANS",
  "property_address": "5300 LAFAYE STREET",
  "property_address_normalized": "5300 LAFAYE STREET",
  "parcel_apn": null,
  "property_type": null,
  "estimated_value_usd": null,
  "mortgage_balance_usd": null,
  "lien_amount_usd": null,
  "opening_bid_usd": null,
  "winning_bid_usd": 0,
  "owner_occupied": null,
  "property_equity_estimate_usd": null,
  "status": "Pending",
  "lat": null,
  "lng": null,
  "raw_source_fields": "{\"cdccasenumber\":\"2012-5883\",\"defendant\":\"GREGORY DELORIMIER\",...}"
}
```

Download results in **JSON, CSV, or Excel** directly from the Apify Console, or pull them programmatically via the API.

### Use cases

- **Direct mail / lead generation** — build targeted lists of probate, foreclosure, or tax-sale leads by state and county for real estate investors and agents
- **Skip tracing pipelines** — feed defendant/decedent names and last-known addresses into your enrichment or skip-tracing workflow
- **Market research** — track foreclosure and tax-sale volume trends across counties over time with scheduled runs
- **Equity-targeted outreach** — filter on `minEstimatedEquity` to find properties where a source portal publishes both value and mortgage data
- **Compliance and due diligence** — cross-reference case numbers and parties before making an offer

### How it works

1. Go to the [Distressed Property Lead Scraper](https://apify.com/parsebird/distressed-property-scraper) page on Apify Store
2. Click **Try for free** — new users get a free trial to test the Actor before paying
3. Choose your **event types** (or leave empty for all 5) and optionally filter by **state**/**county**
4. Optionally set `dateFrom`/`dateTo`, `minEstimatedEquity`, or `onlyOwnerOccupied` to narrow the feed
5. Click **Start** — the Actor searches the Socrata catalog for matching datasets, pages through each one, and normalizes every row
6. When the run finishes, download your leads as **JSON, CSV, or Excel**, or fetch them via the API

### Use with the Apify API

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("parsebird/distressed-property-scraper").call(run_input={
    "eventTypes": ["foreclosure", "sheriff_sale", "tax_lien"],
    "states": ["LA", "NY"],
    "maxItems": 500,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{item['event_type']} - {item['state']}/{item['county']} - {item.get('property_address') or item.get('case_number')}")
```

**JavaScript**

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

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });

const run = await client.actor('parsebird/distressed-property-scraper').call({
    eventTypes: ['foreclosure', 'sheriff_sale', 'tax_lien'],
    states: ['LA', 'NY'],
    maxItems: 500,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.log(`${item.event_type} - ${item.state}/${item.county} - ${item.property_address || item.case_number}`);
});
```

See the [Apify API documentation](https://docs.apify.com/api/v2) for full reference, or the Actor's **API** tab for ready-to-run request snippets in more languages.

### How much does it cost to run?

This Actor uses **Pay-per-event** pricing — you only pay for leads actually returned, with no separate platform rental fee.

| Plan | Price per event | Price per 1,000 |
|------|-----------------|-----------------|
| Free | $0.0011 | $1.10 |
| Bronze | $0.00099 | $0.99 |
| Silver | $0.00089 | $0.89 |
| Gold | $0.00079 | $0.79 |

One `lead-scraped` event is charged for each record successfully normalized and pushed to the dataset. A 100-lead run costs about $0.11 on the Free plan or $0.079 on Gold; a 5,000-lead multi-county sweep costs about $5.50 (Free) to $3.95 (Gold). Start with the free trial and a low `maxItems` to preview results before scaling up.

### FAQ

**How do I scrape probate and foreclosure records in the US?**
This Actor queries the Socrata open-data network — the same backend used by data.cityofnewyork.us, data.nola.gov, datacatalog.cookcountyil.gov, and other county and state portals. It classifies matching datasets by keyword and dataset category, pages through each one, and normalizes the heterogeneous columns into a single distressed-property schema.

**What data can I get from this scraper?**
Up to 30 normalized fields per record — case numbers, defendant and plaintiff names, property addresses, parcel IDs, sale dates, bid amounts, property types, and owner-occupancy flags where available. Field population depends entirely on what each source dataset publishes; the raw source row is always included in `raw_source_fields` so you can dig deeper.

**Does this scraper need proxies?**
No. Socrata open-data APIs are public, unauthenticated, and don't rate-limit casual use. Leave `proxyConfiguration` at its default (proxy off).

**Can I filter by state, county, or event type?**
Yes. Set `states` to one or more two-letter codes and/or `counties` to county names to restrict which portals get queried. Set `eventTypes` to any subset of `probate`, `foreclosure`, `sheriff_sale`, `tax_lien`, `tax_sale`. Combine with `dateFrom`/`dateTo` and `minEstimatedEquity` to narrow the feed further.

**Which states and counties does it cover?**
24 verified portals across LA (Orleans, East Baton Rouge parishes + state), WA (King County + state), MD (Prince George's, Howard, Montgomery counties + state), CT (state), IL (Cook, Macoupin counties), MA (Middlesex/Cambridge), CO (state), CA (Santa Clara, San Mateo, Riverside, Sonoma counties), NY (NYC, Nassau County + state), NJ (state), OR (state), PA (state), and TX (state). Coverage is limited to portals verified to exist and return real datasets — see the Actor's input schema for the exact state list. It expands as we verify new county/state portals.

**Why don't all records have an address, case number, or dollar amounts?**
Not every source portal publishes every field. A NYC tax lien list, for example, has no defendant name because it lists properties, not court cases; some probate archive indexes have no financial data because they're historical case indexes rather than live filings. Records with no identifying field at all (case number, address, parcel ID, or party name) are dropped rather than returned as an empty shell.

**Can I schedule recurring runs?**
Yes. Use Apify's [Scheduler](https://docs.apify.com/platform/schedules) to run this Actor daily, weekly, or at any interval to catch newly filed cases as portals update.

**Is it legal to scrape this data?**
Yes — every record here comes from a government open-data portal that publishes it specifically for public access via API, not from scraping a private website. You're still responsible for how you use the data (e.g. compliance with your state's telemarketing/solicitation laws if you use it for outreach). See Apify's [blog post on the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) for general background.

**Can I access results via API?**
Yes. Every run's dataset is available through the [Apify API](https://docs.apify.com/api/v2) and client libraries (Python, JavaScript) — see the Actor's **API** tab for ready-made snippets.

**Something not working?**
Open an issue on the Actor's **Issues** tab in Apify Console — the ParseBird team monitors it directly.

### Related Actors

Other lead-generation and business-data Actors from ParseBird:

- [BuildZoom Scraper](https://apify.com/parsebird/buildzoom-scraper) — licensed US contractor data with BZ scores, licenses, and permit history
- [Website Contact Finder](https://apify.com/parsebird/website-contact-finder) — extract emails, phone numbers, and social links from any website
- [Shopify Store Leads Scraper](https://apify.com/parsebird/shopify-store-leads-scraper) — find and enrich Shopify merchant leads

# Actor input Schema

## `eventTypes` (type: `array`):

One or more distressed-property event types to search for. Leave empty for all.

## `states` (type: `array`):

US two-letter state codes. Filters source portals by their geographic scope. Leave empty for all covered states.

## `counties` (type: `array`):

County names, e.g. King, Cook, Orleans. Case-insensitive. Leave empty for all covered counties.

## `dateFrom` (type: `string`):

ISO date (YYYY-MM-DD). Keeps records with a sale\_date or filing\_date on/after this date.

## `dateTo` (type: `string`):

ISO date (YYYY-MM-DD). Keeps records with a sale\_date or filing\_date on/before this date.

## `minEstimatedEquity` (type: `integer`):

Drops records where estimated\_value\_usd minus mortgage\_balance\_usd is below this amount. 0 disables the filter.

## `onlyOwnerOccupied` (type: `boolean`):

When enabled, drops records where owner-occupancy cannot be verified as true from the source data.

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

Hard cap on records returned, counted across all datasets.

## `proxyConfiguration` (type: `object`):

Socrata endpoints are open, unauthenticated APIs and do not need proxies. Leave the defaults (proxy off) unless you have a specific reason to route through one.

## Actor input object example

```json
{
  "eventTypes": [
    "foreclosure",
    "sheriff_sale"
  ],
  "states": [
    "LA",
    "NY"
  ],
  "counties": [],
  "dateFrom": "",
  "dateTo": "",
  "minEstimatedEquity": 0,
  "onlyOwnerOccupied": false,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# 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 = {
    "eventTypes": [
        "foreclosure",
        "sheriff_sale"
    ],
    "states": [
        "LA",
        "NY"
    ],
    "counties": [],
    "dateFrom": "",
    "dateTo": "",
    "minEstimatedEquity": 0,
    "onlyOwnerOccupied": false,
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/distressed-property-scraper").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 = {
    "eventTypes": [
        "foreclosure",
        "sheriff_sale",
    ],
    "states": [
        "LA",
        "NY",
    ],
    "counties": [],
    "dateFrom": "",
    "dateTo": "",
    "minEstimatedEquity": 0,
    "onlyOwnerOccupied": False,
    "maxItems": 100,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/distressed-property-scraper").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 '{
  "eventTypes": [
    "foreclosure",
    "sheriff_sale"
  ],
  "states": [
    "LA",
    "NY"
  ],
  "counties": [],
  "dateFrom": "",
  "dateTo": "",
  "minEstimatedEquity": 0,
  "onlyOwnerOccupied": false,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call parsebird/distressed-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/distressed-property-scraper"
        }
    }
}

```

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/0obeTULunm7OydUFE/builds/UtLR938GIrCeccYj6/openapi.json
