NYC Distressed Property Leads — Violations, Liens, Evictions avatar

NYC Distressed Property Leads — Violations, Liens, Evictions

Pricing

from $13.75 / 1,000 results

Go to Apify Store
NYC Distressed Property Leads — Violations, Liens, Evictions

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

Kyle Maloney

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

an hour ago

Last modified

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):

  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, 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 fieldPopulated
owner_contact (whole object)98.0%
owner_contact.name98.0%
owner_contact.business_address98.0%
owner_contact.type98.0%
owner_contact.corporation0.0% - see note below
owner_corporation (owning LLC)98.0%
owner_full_name (incl. middle initial)98.0%
owner_title66.0%
owner_agent_name98.0%
owner_agent_address98.0%
registration_id100.0%
address / zip / bin / latitude / longitude100.0%
lien_sale_cycle and the other lien_* fields38.0% (only parcels on the lien list)
newest_eviction_date73.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

FieldMeaning
bbl10-digit Borough-Block-Lot parcel id
boroughBorough name
blockTax block, unpadded
lotTax lot, unpadded
addressBest available street address across the contributing datasets
zipZIP code
binNYC Building Identification Number
latitudeWGS84 latitude as published by HPD or DOI
longitudeWGS84 longitude as published by HPD or DOI
community_boardNYC community board
council_districtNYC council district
census_tractCensus tract as published by HPD

Distress signals

FieldMeaning
distress_scoreWeighted score (formula above), sorted descending
signals_presentWhich of violations / lien_sale / evictions fired
open_violations_aOpen class-A (non-hazardous) violations in the window
open_violations_bOpen class-B (hazardous) violations in the window
open_violations_cOpen class-C (immediately hazardous) violations in the window
open_violations_iOpen 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_totalA + B + C + I
rent_impairing_violationsOpen violations HPD flags rent-impairing (tenants may deposit rent with the court)
newest_violation_dateIssue date of the most recent open violation counted
oldest_violation_dateIssue date of the oldest open violation counted in the window
lien_sale_cycleMost severe lien-sale stage, or null when the parcel is not on the list
lien_sale_monthList month of that most severe notice
lien_notice_countHow many lien-sale notices the parcel received in the window
lien_water_debt_onlyTrue when the lien listing is water/sewer debt only
lien_building_classNYC building class as published on the lien-sale list
lien_tax_class_codeNYC tax class code as published on the lien-sale list
evictions_countMarshal-executed evictions at the parcel in the window
evictions_residentialOf those, marked Residential
evictions_commercialOf those, marked Commercial
newest_eviction_dateExecution date of the most recent eviction

Owner and contact

FieldMeaning
owner_contactBest single HPD registration contact: {type, name, corporation, business_address}, or null
owner_contact_checkedTrue when the HPD contact source answered this run. When false, a null contact means "not checked", not "no contact on file"
owner_contact_foundTrue/false only when owner_contact_checked is true; null otherwise
owner_contact_countHow many HPD contact rows exist for the parcel
owner_corporationBest corporation name across ALL contacts - usually the owning LLC
owner_full_nameTop-ranked contact name including middle initial
owner_titleTitle as filed with HPD (MEMBER, PRINCIPAL, TREASURER...)
owner_contact_typesEvery HPD contact type present for the registration
owner_agent_nameFiled Agent or SiteManager - often the reachable party when the owner is an LLC
owner_agent_addressBusiness address of that Agent or SiteManager
owner_contacts_allUp to 12 contacts, each {type, name, middle_initial, title, corporation, contact_description, business_address}
registration_idThe HPD registration id used for the join

Run provenance and source health

FieldMeaning
violations_statusok / unavailable for the HPD violation read
lien_sale_statusok / unavailable for the tax-lien-sale read
evictions_statusok / unavailable for the marshal-eviction read
contacts_statusok / unavailable for the HPD contact join
registrations_statusok / unavailable / not_applicable for the registration-roll fallback
sources_failedDataset URLs that did not answer. Empty on a healthy run
partial_runTrue when any contributing source did not answer
violations_max_dateNewest record in the HPD violation dataset at run time
lien_sale_max_dateNewest list month in the lien-sale dataset at run time
evictions_max_dateNewest execution date in the eviction dataset at run time
violations_cutoffEarliest violation issue date counted
lien_sale_cutoffEarliest lien-sale list month counted
evictions_cutoffEarliest eviction execution date counted
evictions_without_bbl_in_windowExecuted evictions in this borough and window that carry no BBL upstream and cannot be attributed to a parcel
lookback_monthsWindow used for this run
data_as_ofUTC date the run executed
unmapped_borough_rowsEviction 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_rowsSame, 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_noteDetail of any tolerated unknown value: the value, its row count, and its share of its group. null when every token was recognised
source_urlsNYC 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 violationid ascending, 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 the count(*) the service itself reports and fails the run if it cannot.
  • lien_water_debt_only was inverted on the freshest rows. The 2025 lien cycle emits the short tokens Y and N alongside YES/NO; v1.0 compared against the literal string YES, so all 802 Y rows 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: null for every parcel. On a lead product that is a confident wrong answer. Rows now carry contacts_status and owner_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_corporation now 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_ind was 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=10000 with no $order truncated 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_count is 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 as evictions_without_bbl_in_window.
  • Contact join path: registrationid carried 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_month values 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 lookbackMonths to 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.

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

ActorWhat it adds
NYC ACRIS Deed Transfer IntelWho actually bought and sold - deed price, LLC-buyer, cash-sale and out-of-state-buyer flags
NYC Landlord Registry Lead ListThe owner's whole portfolio - filter to landlords holding 5-50 buildings, with business contact
Parcel Owner LookupAddress 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.