NYC Distressed Property Leads — Violations, Liens, Evictions
Pricing
from $13.75 / 1,000 results
NYC Distressed Property Leads — Violations, Liens, Evictions
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.
Pricing
from $13.75 / 1,000 results
Rating
0.0
(0)
Developer
Kyle Maloney
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
an hour ago
Last modified
Categories
Share
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):
- Open HPD housing maintenance code violations (class A / B / C)
- DOF tax lien sale notices (90/60/30/10-Day Notice and Final Sale cycles)
- Marshal-executed evictions
Every parcel that shows enough distinct signals gets a weighted distress score, the registered owner, the owning LLC, and the managing agent from HPD registrations, and comes out ranked highest-distress first - ready for direct mail, skip tracing, cold calling, or acquisition underwriting.
Who it is for
- Real estate investors and wholesalers hunting off-market, pre-foreclosure-adjacent deals
- Agents and brokers prospecting listings from owners under financial or regulatory pressure
- Lenders, note buyers and tax-lien investors screening collateral risk by parcel
- PropTech and 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 x1.0, 60 Day x1.2, 30 Day x1.5,
10 Day x1.8, Final Sale x2.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
{"borough": "BRONX","minSignals": 2,"lookbackMonths": 12,"maxResults": 100}
All fields are optional - an empty input runs the Bronx with the defaults above.
borough accepts a name or a code 1-5; anything else fails the run before any row
is emitted or billed.
How complete is the contact data? (measured, not claimed)
Measured on the actor's own prefill (Bronx, 12 months, minSignals 2, 100 results) against the live datasets on 2026-08-01, n = 100 leads:
| Contact / identity field | Populated |
|---|---|
owner_contact (whole object) | 98.0% |
owner_contact.name | 98.0% |
owner_contact.business_address | 98.0% |
owner_contact.type | 98.0% |
owner_contact.corporation | 0.0% - see note below |
owner_corporation (owning LLC) | 98.0% |
owner_full_name (incl. middle initial) | 98.0% |
owner_title | 66.0% |
owner_agent_name | 98.0% |
owner_agent_address | 98.0% |
registration_id | 100.0% |
address / zip / bin / latitude / longitude | 100.0% |
lien_sale_cycle and the other lien_* fields | 38.0% (only parcels on the lien list) |
newest_eviction_date | 73.0% (only parcels with an eviction) |
Mean HPD contacts on file per lead: 4.4.
owner_contact.corporation reads 0.0% because owner_contact is a single
best-ranked contact and the top rank is a natural person (IndividualOwner or
HeadOfficer), who never carries a corporation name. The owning entity is on a
different contact row for the same registration. v1.1 publishes it as
owner_corporation rather than leaving it fetched-and-discarded, and
owner_contacts_all carries up to 12 contacts so nothing is lost. The v1.0 field
is unchanged so existing pipelines keep working.
2.0% of leads have no HPD contact at all: those are buildings that never
registered with HPD (small owner-occupied homes, many commercial parcels). They
are never dropped - they emit with owner_contact: null,
owner_contact_checked: true and owner_contact_found: false.
Output fields
Parcel identity
| Field | Meaning |
|---|---|
bbl | 10-digit Borough-Block-Lot parcel id |
borough | Borough name |
block | Tax block, unpadded |
lot | Tax lot, unpadded |
address | Best available street address across the contributing datasets |
zip | ZIP code |
bin | NYC Building Identification Number |
latitude | WGS84 latitude as published by HPD or DOI |
longitude | WGS84 longitude as published by HPD or DOI |
community_board | NYC community board |
council_district | NYC council district |
census_tract | Census tract as published by HPD |
Distress signals
| Field | Meaning |
|---|---|
distress_score | Weighted score (formula above), sorted descending |
signals_present | Which of violations / lien_sale / evictions fired |
open_violations_a | Open class-A (non-hazardous) violations in the window |
open_violations_b | Open class-B (hazardous) violations in the window |
open_violations_c | Open class-C (immediately hazardous) violations in the window |
open_violations_i | Open class-I violations. HPD stopped issuing class I in Aug 2014, so this is 0 in any reachable window - it exists so those rows are counted rather than silently discarded |
open_violations_total | A + B + C + I |
rent_impairing_violations | Open violations HPD flags rent-impairing (tenants may deposit rent with the court) |
newest_violation_date | Issue date of the most recent open violation counted |
oldest_violation_date | Issue date of the oldest open violation counted in the window |
lien_sale_cycle | Most severe lien-sale stage, or null when the parcel is not on the list |
lien_sale_month | List month of that most severe notice |
lien_notice_count | How many lien-sale notices the parcel received in the window |
lien_water_debt_only | True when the lien listing is water/sewer debt only |
lien_building_class | NYC building class as published on the lien-sale list |
lien_tax_class_code | NYC tax class code as published on the lien-sale list |
evictions_count | Marshal-executed evictions at the parcel in the window |
evictions_residential | Of those, marked Residential |
evictions_commercial | Of those, marked Commercial |
newest_eviction_date | Execution date of the most recent eviction |
Owner and contact
| Field | Meaning |
|---|---|
owner_contact | Best single HPD registration contact: {type, name, corporation, business_address}, or null |
owner_contact_checked | True when the HPD contact source answered this run. When false, a null contact means "not checked", not "no contact on file" |
owner_contact_found | True/false only when owner_contact_checked is true; null otherwise |
owner_contact_count | How many HPD contact rows exist for the parcel |
owner_corporation | Best corporation name across ALL contacts - usually the owning LLC |
owner_full_name | Top-ranked contact name including middle initial |
owner_title | Title as filed with HPD (MEMBER, PRINCIPAL, TREASURER...) |
owner_contact_types | Every HPD contact type present for the registration |
owner_agent_name | Filed Agent or SiteManager - often the reachable party when the owner is an LLC |
owner_agent_address | Business address of that Agent or SiteManager |
owner_contacts_all | Up to 12 contacts, each {type, name, middle_initial, title, corporation, contact_description, business_address} |
registration_id | The HPD registration id used for the join |
Run provenance and source health
| Field | Meaning |
|---|---|
violations_status | ok / unavailable for the HPD violation read |
lien_sale_status | ok / unavailable for the tax-lien-sale read |
evictions_status | ok / unavailable for the marshal-eviction read |
contacts_status | ok / unavailable for the HPD contact join |
registrations_status | ok / unavailable / not_applicable for the registration-roll fallback |
sources_failed | Dataset URLs that did not answer. Empty on a healthy run |
partial_run | True when any contributing source did not answer |
violations_max_date | Newest record in the HPD violation dataset at run time |
lien_sale_max_date | Newest list month in the lien-sale dataset at run time |
evictions_max_date | Newest execution date in the eviction dataset at run time |
violations_cutoff | Earliest violation issue date counted |
lien_sale_cutoff | Earliest lien-sale list month counted |
evictions_cutoff | Earliest eviction execution date counted |
evictions_without_bbl_in_window | Executed evictions in this borough and window that carry no BBL upstream and cannot be attributed to a parcel |
lookback_months | Window used for this run |
data_as_of | UTC date the run executed |
unmapped_borough_rows | Eviction rows whose borough token this build does not recognise. Below the drift tolerance, so the run continued, but they are excluded from the score rather than mapped to a guess. 0 = checked, nothing unmapped |
unmapped_vocabulary_rows | Same, totalled across all eight closed-vocabulary gates (violation class and status, lien cycle, water-debt flag, eviction borough, contact type, property type, possession type) |
vocabulary_drift_note | Detail of any tolerated unknown value: the value, its row count, and its share of its group. null when every token was recognised |
source_urls | NYC Open Data pages that contributed to the row |
Freshness: dataset-anchored lookback
The lien-sale list is published in cycles and lags the other sources (currently
through the 2025-06 cycle). Every lookback window is therefore anchored to
that dataset's own most-recent record date, not today, and each anchor is
published on the row (violations_max_date, lien_sale_max_date,
evictions_max_date). The run log prints them too.
What v1.1 fixed (2026-08-01)
All five sources were re-probed live and the actor was rebuilt around what they actually return. Nothing was removed or renamed.
- The default run was reading 100,000 of 165,733 open Bronx violations. v1.0
paged at a hard 10 x 10,000 ceiling with no row-count reconciliation. Because
the read is ordered by
violationidascending, the missing 39.7% was the newest data - every open violation issued after 2026-05-04 was invisible. Effect on the shipped prefill: 25 of the 100 published leads did not belong in the top 100, 25 genuine top-100 leads were never seen, and all 75 survivors had an understated score (mean understatement 150 points). Worst case, 2338 Morris Avenue: published 66 open class-B violations against a true 244, and a score of 266 against a true 880. Every read now reconciles against thecount(*)the service itself reports and fails the run if it cannot. lien_water_debt_onlywas inverted on the freshest rows. The 2025 lien cycle emits the short tokensYandNalongsideYES/NO; v1.0 compared against the literal stringYES, so all 802Yrows nationwide (176 in the Bronx window alone) were published as "not water-debt-only" - the opposite of the truth, and it makes a weak signal look like a strong one.- A contacts outage was published as "no contact on file". The whole
enrichment sat inside one catch that emitted
owner_contact: nullfor every parcel. On a lead product that is a confident wrong answer. Rows now carrycontacts_statusandowner_contact_checked. - The owning LLC was fetched on every row and thrown away, along with the
managing agent, the title and the middle initial.
owner_corporationnow reads 98.0% populated on the prefill where it read 0.0%. - Class-I violations were silently discarded by a bare
else continue. residential_commercial_indwas fetched and dropped in the mapper.- Contact paging could starve a batch. One HPD registration carries 8,688
contact rows (registration 911741), so a 100-id batch under a flat
$limit=10000with no$ordertruncated non-deterministically. - A bad borough raised a bare module-level throw; it now fails loudly with an actionable message and bills nothing.
Honest notes (read before you buy)
- NYC-only. The five sources are NYC Open Data (Socrata).
- A distress score needs all three signal sources. A score built on two of them is not a smaller answer, it is a wrong one, and it is indistinguishable on the row from a parcel that genuinely has no lien and no eviction. So if any signal source fails, the run fails and bills nothing rather than publishing a partial score.
evictions_countis a floor. Roughly 5% of executed evictions carry no BBL in the city dataset and cannot be attributed to a parcel. The exact count for your run is published on every row asevictions_without_bbl_in_window.- Contact join path:
registrationidcarried on the HPD violation rows, with a fallback through HPD Registrations (tesw-yqqr) by borough/block/lot for parcels flagged only by liens or evictions. Buildings that never registered with HPD emit with a null contact and are never dropped. - Lien-sale data vintage: the DOF list updates only when the city runs a
lien-sale cycle; months-old
lien_sale_monthvalues between cycles are the source, not a bug. The run fails if that list is ever rolled back earlier than the 2025-06 cycle this build was verified against. - Tenant privacy: eviction records are used only as a per-parcel count. Respondent names, court index numbers, docket numbers and marshal names are never even requested. This is a landlord-side product.
- Violation counts cover open violations issued within the lookback window;
raise
lookbackMonthsto widen. - This is a screening tool, not a determination. Verify anything you act on against the city record.
Use as an MCP tool
This actor works as a tool for AI agents (Claude, Cursor and others) via mcp.apify.com - ask your agent for "the 50 most distressed parcels in Brooklyn with owner contacts" and it can call this actor directly. Every output field carries a description in the dataset schema, so an agent can chain it without guessing.
FAQ
How do I find distressed properties in NYC from 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 from a BBL? Each lead carries the best HPD registration contact, the owning corporation, the managing agent and up to 12 contacts in total, with business mailing addresses.
Can I run all five boroughs? Yes - run the actor once per borough. 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). Runs that fail a pre-flight check emit nothing
and bill nothing.
Related actors - the NYC investor shelf
All key on the same borough-block-lot (BBL), so they stack into one workflow:
| Actor | What it adds |
|---|---|
| NYC 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 | The owner's whole portfolio - filter to landlords holding 5-50 buildings, with business contact |
| Parcel Owner Lookup | Address to 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, then pull the owner's full portfolio and mailing contact from the HPD registry.