# NYC Distressed Property Leads — Violations, Liens, Evictions (`malonestar/distressed-property-signal-stacker`) Actor

NYC motivated-seller leads: stacks open HPD violations, tax lien sale notices, and executed evictions per parcel (BBL), scores distress, and attaches the registered owner or agent contact. Ranked leads for investors, wholesalers, and agents from keyless NYC open data. Pay per result.

- **URL**: https://apify.com/malonestar/distressed-property-signal-stacker.md
- **Developed by:** [Kyle Maloney](https://apify.com/malonestar) (community)
- **Categories:** Real estate, Lead generation, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $13.75 / 1,000 results

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

## NYC Distressed Property Leads — Violations, Liens, Evictions

Find **motivated-seller leads in New York City** by stacking three official distress
signals per tax parcel (BBL):

1. **Open HPD housing maintenance code violations** (class A / B / C)
2. **DOF tax lien sale notices** (90/60/30/10-Day Notice and Final Sale cycles)
3. **Marshal-executed evictions**

Every parcel that shows enough distinct signals gets a **weighted distress score**,
the **registered owner or managing agent contact** from HPD registrations, and comes
out ranked highest-distress first — ready for direct mail, skip tracing, cold calling,
or acquisition underwriting.

### Who it's for

- **Real estate investors & wholesalers** hunting off-market, pre-foreclosure-adjacent deals
- **Agents & brokers** prospecting listings from owners under financial/regulatory pressure
- **Lenders, note buyers & tax-lien investors** screening collateral risk by parcel
- **PropTech & data teams** who want a scored, deduplicated per-BBL feed instead of three raw city dumps

### How the score works

`distress_score = openC*3 + openB*2 + openA*1 + lien(10 * cycle multiplier) + evictions*5`

Lien-sale cycle escalates the weight: 90 Day Notice ×1.0 → 60 Day ×1.2 → 30 Day ×1.5 →
10 Day ×1.8 → **Final Sale ×2.0**. A parcel with 1 open class-C violation, a 30-Day
lien notice, and 2 executed evictions scores `3 + 15 + 10 = 28`.

`signals_present` lists which of `violations`, `lien_sale`, `evictions` the parcel
shows; `minSignals` controls how many distinct types are required (default 2).

### Example input

```json
{
  "borough": "BRONX",
  "minSignals": 2,
  "lookbackMonths": 12,
  "maxResults": 100
}
````

All fields are optional — an empty input runs the Bronx with the defaults above.

### Output fields

| Field | Meaning |
| --- | --- |
| `bbl` | 10-digit Borough-Block-Lot parcel id |
| `borough`, `block`, `lot` | Parcel identifiers |
| `address`, `zip` | Best available street address |
| `distress_score` | Weighted score (see above), sorted DESC |
| `open_violations_a/b/c` | Open HPD violations by class in the lookback window |
| `lien_sale_cycle` | Most severe lien-sale stage, or `null` |
| `lien_water_debt_only` | `true` if the lien listing is water/sewer debt only |
| `evictions_count` | Executed evictions in the lookback window |
| `signals_present` | Which signal types fired |
| `owner_contact` | `{type, name, corporation, business_address}` or `null` |
| `lookback_months` | Window used for this run |
| `source_urls` | NYC Open Data pages that contributed to the row |

### Freshness: dataset-anchored lookback

The lien-sale list is published in cycles and can lag other sources (currently
through the **2025-06 cycle**). To avoid silently returning nothing, every lookback
window is anchored to **that dataset's own most-recent record date, not today**.
The run log prints each dataset's max date so you can see exactly what vintage you
got.

### Honest notes (read before you buy)

- **NYC-only v1.** The five sources are NYC Open Data (Socrata); other metros may follow.
- **Contact join path shipped:** the owner/agent contact is joined via `registrationid`
  carried on the HPD violations rows, with a fallback lookup through the HPD
  Registrations dataset (`tesw-yqqr`) by borough/block/lot for parcels flagged only by
  liens or evictions. Buildings that never registered with HPD (small owner-occupied
  homes, many commercial parcels) emit with `owner_contact: null` — they are **never
  dropped**.
- **Lien-sale data vintage:** the DOF list updates only when the city runs a lien-sale
  cycle; expect months-old `month` values between cycles. That is the source, not a bug.
- **Tenant privacy:** eviction records are used only as a per-parcel count. Respondent
  (tenant) names, court index numbers, docket numbers, and marshal names are never
  fetched into the output. This is a landlord-side product.
- Violation counts cover **open violations issued within the lookback window** (older
  still-open violations are out of window by design — raise `lookbackMonths` to widen).

### Use as an MCP tool

This actor works as a tool for AI agents (Claude, Cursor, etc.) via
[mcp.apify.com](https://mcp.apify.com) — ask your agent for "the 50 most distressed
parcels in Brooklyn with owner contacts" and it can call this actor directly.

### FAQ

**How do I find distressed properties in NYC for free data sources?**
This actor does it for you: it merges the three public distress feeds per parcel and
scores them, so you skip the joins, BBL normalization, and cycle parsing.

**Is this a foreclosure or pre-foreclosure list?**
No — it is upstream of foreclosure: code violations, tax-lien-sale notices, and
evictions are the pressure signals that often precede a distressed sale.

**How do I get the property owner's contact info from a BBL?**
Each lead includes the best HPD registration contact (owner first, then head officer,
then agent) with its business mailing address when the building is registered.

**Can I run all five boroughs?**
Yes — run the actor once per borough (5 runs). Per-borough runs keep results focused
and your per-result spend predictable.

**How is this priced?**
Pay-per-result: you are charged only for the ranked parcel leads actually emitted
(cap with `maxResults`). Zero-match runs cost only the actor start.

### Related actors — the NYC investor shelf

All three key on the same borough-block-lot (BBL), so they stack into one workflow:

| Actor | What it adds |
|---|---|
| [NYC ACRIS Deed Transfer Intel](https://apify.com/malonestar/acris-deed-transfer-intel) | Who actually bought and sold — deed price, LLC-buyer, cash-sale and out-of-state-buyer flags |
| [NYC Landlord Registry Lead List](https://apify.com/malonestar/nyc-landlord-registry-lead-list) | The owner's whole portfolio — filter to landlords holding 5–50 buildings, with business contact |
| [Parcel Owner Lookup](https://apify.com/malonestar/parcel-owner-lookup) | Address → owner of record, for one-off checks outside NYC too |

Typical play: score distress here → check ACRIS for recent transfer activity on the same BBL → pull the owner's full portfolio and mailing contact from the HPD registry.

# Actor input Schema

## `borough` (type: `string`):

NYC borough to scan. Accepts a name (MANHATTAN, BRONX, BROOKLYN, QUEENS, STATEN ISLAND) or a borough code 1-5. One borough per run keeps runs fast and cheap.

## `minSignals` (type: `integer`):

Only emit parcels showing at least this many DIFFERENT distress signal types (open violations, tax-lien-sale notice, executed evictions). 2 = solid motivated-seller leads; 3 = only the most distressed parcels; 1 = everything with any signal.

## `lookbackMonths` (type: `integer`):

How many months of history to count, anchored to each dataset's own most-recent record date (not today) so a lagging source like the lien-sale list still yields its latest cycle. Applies to violation issue dates, lien-sale list months, and eviction execution dates.

## `maxResults` (type: `integer`):

Maximum number of ranked parcel leads to emit (highest distress score first). You are billed per result, so this caps your spend.

## Actor input object example

```json
{
  "borough": "BRONX",
  "minSignals": 2,
  "lookbackMonths": 12,
  "maxResults": 100
}
```

# Actor output Schema

## `results` (type: `string`):

The default dataset of ranked distressed-parcel leads.

# 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 = {
    "borough": "BRONX",
    "minSignals": 2,
    "lookbackMonths": 12,
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("malonestar/distressed-property-signal-stacker").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 = {
    "borough": "BRONX",
    "minSignals": 2,
    "lookbackMonths": 12,
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("malonestar/distressed-property-signal-stacker").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "borough": "BRONX",
  "minSignals": 2,
  "lookbackMonths": 12,
  "maxResults": 100
}' |
apify call malonestar/distressed-property-signal-stacker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=malonestar/distressed-property-signal-stacker",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "NYC Distressed Property Leads — Violations, Liens, Evictions",
        "description": "NYC motivated-seller leads: stacks open HPD violations, tax lien sale notices, and executed evictions per parcel (BBL), scores distress, and attaches the registered owner or agent contact. Ranked leads for investors, wholesalers, and agents from keyless NYC open data. Pay per result.",
        "version": "1.0",
        "x-build-id": "0UhsAfAggDYxeW6G0"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/malonestar~distressed-property-signal-stacker/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-malonestar-distressed-property-signal-stacker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/malonestar~distressed-property-signal-stacker/runs": {
            "post": {
                "operationId": "runs-sync-malonestar-distressed-property-signal-stacker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/malonestar~distressed-property-signal-stacker/run-sync": {
            "post": {
                "operationId": "run-sync-malonestar-distressed-property-signal-stacker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "borough": {
                        "title": "Borough",
                        "enum": [
                            "MANHATTAN",
                            "BRONX",
                            "BROOKLYN",
                            "QUEENS",
                            "STATEN ISLAND"
                        ],
                        "type": "string",
                        "description": "NYC borough to scan. Accepts a name (MANHATTAN, BRONX, BROOKLYN, QUEENS, STATEN ISLAND) or a borough code 1-5. One borough per run keeps runs fast and cheap.",
                        "default": "BRONX"
                    },
                    "minSignals": {
                        "title": "Minimum distinct signals",
                        "minimum": 1,
                        "maximum": 3,
                        "type": "integer",
                        "description": "Only emit parcels showing at least this many DIFFERENT distress signal types (open violations, tax-lien-sale notice, executed evictions). 2 = solid motivated-seller leads; 3 = only the most distressed parcels; 1 = everything with any signal.",
                        "default": 2
                    },
                    "lookbackMonths": {
                        "title": "Lookback window (months)",
                        "minimum": 1,
                        "maximum": 60,
                        "type": "integer",
                        "description": "How many months of history to count, anchored to each dataset's own most-recent record date (not today) so a lagging source like the lien-sale list still yields its latest cycle. Applies to violation issue dates, lien-sale list months, and eviction execution dates.",
                        "default": 12
                    },
                    "maxResults": {
                        "title": "Max results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of ranked parcel leads to emit (highest distress score first). You are billed per result, so this caps your spend.",
                        "default": 100
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
