Distressed Property Leads - NYC, Detroit, Philly & Chicago avatar

Distressed Property Leads - NYC, Detroit, Philly & Chicago

Pricing

from $13.75 / 1,000 results

Go to Apify Store
Distressed Property Leads - NYC, Detroit, Philly & Chicago

Distressed Property Leads - NYC, Detroit, Philly & Chicago

Motivated-seller leads for New York City, Detroit, Philadelphia and Chicago. Stacks open code violations, blight tickets, tax liens, evictions, vacant-building complaints and scofflaw listings per property, scores distress, and attaches the owner name and mailing address. Keyless government data.

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

4 days ago

Last modified

Share

Distressed Property Leads - NYC, Detroit, Philadelphia, Chicago

Find motivated-seller leads by stacking official municipal distress signals per property and attaching the owner name and mailing address each city publishes. Four metros, all from keyless government sources.

  • New York City - open HPD violations, DOF tax-lien-sale notices, marshal evictions
  • Detroit - blight tickets, unpaid judgment balances, vacant property registrations
  • Philadelphia - open L&I code violations, with the Notice of Violation PDF
  • Chicago - building violations, 311 vacant-building complaints, Building Code Scofflaw listings

Every property that shows enough distinct signals gets a distress score, the owner name and mailing address, and comes out ranked highest-distress first - ready for direct mail, skip tracing, cold calling, or acquisition underwriting. Runs default to New York City; see Metros covered below.

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

Metros covered

metros selects which city pipelines run. It defaults to ["nyc"], which is exactly what this actor did before multi-metro support, so every saved task, API caller and MCP client that omits the field is unaffected and every New York output field keeps its original name and meaning.

MetroDistress signalsOwner nameOwner mailing addressMatch method
nycHPD violations, DOF tax-lien-sale notices, marshal evictionsHPD registrationHPD registration contactBBL
detroitBlight tickets, unpaid judgment balances, BSEED vacant property registrationsOn the ticket row (99.9998% populated, measured live)On the ticket row, plus assessor taxpayer recordParcel ID
philadelphiaL&I open code violations, with the Notice of Violation PDFOn the violation row (98.1% of open violations)OPA assessor rollOPA account number
chicagoBuilding violations, 311 Vacant/Abandoned Building Complaints, Building Code Scofflaw listingsCook County assessor roll, or the scofflaw defendantCook County assessor rollExact address only

Detroit and Philadelphia publish the sellable field on the violation record itself, so no address matching is involved at all. Chicago publishes neither an owner nor a parcel ID on either signal feed, so it is matched to the Cook County parcel universe on an exact address: no street scan, no nearest-house ladder, no fuzzy fallback. Its owner-match rate is therefore lower than Detroit's or Philadelphia's, and the actual rate for the run is published on every row as metro_owner_contact_rate rather than quoted from this page.

Each metro is a separate full-city scan and is billed per result. Adding a metro roughly adds its own row count to your bill, so add them one at a time.

{
"metros": ["detroit"],
"minSignals": 2,
"lookbackMonths": 12,
"maxResults": 100
}

borough applies to New York City only and is ignored by the other three, which are scanned city-wide.

Philadelphia publishes one signal type, and the threshold respects that

minSignals counts distinct signal types, and each city publishes a different number of them: Detroit and Chicago three each, Philadelphia one. A Philadelphia property therefore cannot ever show two distinct types, so a literal minSignals: 2 there would return an empty dataset for a city with tens of thousands of open violations - and an empty dataset reads as "no distressed property in Philadelphia", which is false.

The threshold is therefore clamped to what the city can actually publish, and both numbers ship on every row as metro_min_signals_requested and metro_min_signals_applied, with metro_min_signals_note explaining the difference whenever there is one. Nothing is clamped in Detroit or Chicago below 3. Raising minSignals there still narrows the list exactly as it does in New York.

What is deliberately NOT here

  • Tax delinquency is not a v1 signal in any of the three new metros. Philadelphia's delinquency table is frozen at year_month 202206 and says so nowhere in its own response; Cook County's entire tax-sale family is tagged inactive with data last updated in 2016; Wayne County publishes a 2016 snapshot. Presenting any of them as current would be a confident wrong answer. The Philadelphia vintage is still read on every run and published as tax_delinquency_vintage_not_used inside metro_data_vintage, so if that layer ever goes live again the run will say so.
  • Rental registrations are published but never scored. Registering a rental is compliance, not distress.
  • Tax-exempt status is a scoring modifier, not a signal type, so minSignals means the same thing before and after owner enrichment.
  • Houston and Dallas are not covered. Houston's code-enforcement data is XLSX only and last updated 2023-06-09; Dallas publishes no keyless owner roll.

Multi-metro output fields (Detroit, Philadelphia, Chicago)

New York rows keep the v1.2 shape exactly. The fields below appear on rows from the three new metros. Anything a metro does not publish is null, which means not checked or not published - it never means checked-and-negative.

Property identity

FieldMeaning
metroWhich pipeline produced the row: detroit, philadelphia or chicago. Absent on New York rows
metro_parcel_idDetroit parcel_id with its trailing period stripped, the Philadelphia OPA account number, or the Cook County PIN when exactly one PIN matched
metro_parcel_id_typedetroit_parcel, phila_opa or cook_pin. null when no unambiguous identifier could be attached
property_keyThe key the property was rolled up on: a parcel id in Detroit and Philadelphia, a normalized situs address in Chicago
property_key_typedetroit_parcel, phila_opa or chicago_address
property_address / property_city / property_state / property_zipSitus address as published by the contributing source
neighborhoodNeighborhood, where a contributing source publishes one

Distress signals

FieldMeaning
metro_signal_typesDistinct signal types present: code_violation, unpaid_judgment, vacant_building, vacant_registration, scofflaw_listing
metro_signal_countHow many distinct types this property shows, compared against minSignals
code_violation_countOpen code violations or blight tickets counted inside the window
newest_code_violation_date / oldest_code_violation_dateDate range of the counted violations
code_violation_examplesUp to five counted violations, each with type, code, date, status, reference and url
code_violation_nov_urlPhiladelphia only: direct link to the published Notice of Violation PDF
vacant_complaint_countChicago 311 Vacant/Abandoned Building Complaints for this address in the window, matched on the exact sr_type
vacant_complaint_duplicate_countHow many of those 311 itself flags as duplicates. Excluded from the score so re-reports cannot inflate it
vacant_complaint_open_countHow many are still Open
vacant_registration_countDetroit BSEED vacant property registrations for this parcel in the window
newest_vacant_signal_dateMost recent vacant complaint or vacant registration date
rental_registration_countDetroit BSEED rental registrations. Context only, never scored
rental_registration_typeRegistration type as filed
newest_rental_registration_dateDate of the most recent rental registration
blight_ticket_countDetroit blight tickets counted in the window, including paid ones
unpaid_ticket_countHow many still carry a balance due
unpaid_balance_totalTotal outstanding judgment balance in dollars. null when no source published an amount, never 0 as a stand-in for unknown
newest_ticket_dispositionHearing disposition, e.g. Responsible by Default
scofflaw_listedtrue when the address is on the Chicago Building Code Scofflaw list. null in metros that publish no equivalent
scofflaw_case_number / scofflaw_list_dateCircuit court case number and building list date behind the listing
scofflaw_owner_rawThe defendant_owner string exactly as Chicago publishes it, retained even when the Cook roll supplied a better contact

Owner and contact - the sellable fields

FieldMeaning
owner_nameOwner or taxpayer name as published, verbatim. Never parsed into first/last
owner_name_rawThe same string, kept alongside any normalization so nothing is lost
owner_name_conventionWhich convention produced it: detroit_ticket_owner, detroit_taxpayer, phila_opa_owner, cook_mail_name or chicago_scofflaw
owner_name_convention_notePlain-English description of that convention
owner_name_sourceon_violation_row, assessor_roll or scofflaw_list
owner_partiesChicago scofflaw defendant_owner split on its pipe delimiter, so a two-party listing is not presented as one name
owner_mailing_addressFull deliverable mailing address, comma-joined. This is the field the product is sold on
owner_mailing_street / owner_mailing_city / owner_mailing_state / owner_mailing_zip / owner_mailing_countryComponents of the same address
owner_mailing_sourceon_violation_row or assessor_roll
owner_lookup_statusok = an owner record was found. no_match = the lookup ran and found nothing, which is a measurement. unavailable is never published: a source that does not answer fails the run instead
address_match_methodon_row, parcel_id or exact_address
cook_pin_candidate_countHow many Cook PINs matched the address exactly. Greater than 1 means a condo or multi-PIN building, and no single PIN is asserted
enrichedtrue only when the row carries both an owner name and a deliverable mailing address
is_absenteeOwner mailing address differs from the property address. null when either side was not retrieved
is_out_of_stateOwner mailing state differs from the property state. null when the mailing state was not retrieved
is_entity_ownerOwner name contains an LLC / INC / TRUST / LP token. null when no owner name was retrieved
non_owner_occupiedDetroit only: true when the Principal Residence Exemption is 0, which is the assessor stating the owner does not live there
owner_occupied_pctDetroit Principal Residence Exemption percentage (0-100). null when the assessor row was not joined, never coerced to 0

Three metros, three name conventions. Philadelphia is surname-first and unpunctuated (ROMERO ANGEL), Detroit's taxpayer field is comma-delimited (RIVERS, KRISTINA), and a Cook County mailing name can hold two people in one field (BARRY ROBERTS & GLORIA). The raw string always ships, the convention is named on the row, and no cross-source match is ever keyed on a parsed name.

Assessor detail

FieldMeaning
assessed_value / taxable_valueDetroit assessed and taxable value in dollars
market_valuePhiladelphia OPA market value
last_sale_date / last_sale_priceMost recent recorded sale the assessor publishes
year_builtYear built as published
property_class_descriptionAssessor property class or category description
land_use_descriptionDetroit assessor use-code description
is_improvedDetroit: true when the parcel carries a structure, false for vacant land
total_acreageDetroit parcel acreage
tax_status_code / tax_status_descriptionDetroit assessor tax status verbatim, e.g. TAXABLE or EXEMPT (211.7D). Treated as an open vocabulary
tax_exempttrue when the tax status begins with EXEMPT. null when the assessor row was not joined
homestead_exemptionPhiladelphia OPA homestead exemption amount
cook_property_class / cook_townshipCook County assessor property class code and township
parcel_modified_dateDetroit: the assessor row's own modified date, published instead of asserting a vintage from the layer description

Per-source status - every layer reports its own outcome

ok means that source answered and its full result set was read and reconciled against the count the source itself reports. null means not checked - it is what a Detroit row carries for a Philadelphia layer. A source that fails does not produce a status of false; it fails the whole run.

FieldSource
detroit_blight_tickets_statusDetroit blight tickets
detroit_parcels_statusDetroit assessor parcel roll
detroit_vacant_registrations_statusDetroit BSEED vacant property registrations
detroit_rental_registrations_statusDetroit BSEED rental registrations
phila_violations_statusPhiladelphia L&I violations
phila_opa_statusPhiladelphia OPA assessor roll
chicago_building_violations_statusChicago building violations
chicago_vacant_311_statusChicago 311 vacant-building complaints, with the lot-mowing negative control proving the filter discriminates
chicago_scofflaw_statusChicago Building Code Scofflaw list
cook_assessor_statusCook County parcel universe

Score, coverage and run provenance

FieldMeaning
metro_distress_score0-100 additive score. A different field from the New York distress_score, which is an unbounded weighted sum with a live meaning to existing buyers
metro_distress_reasonsEvery component that contributed, with its point value
metro_distress_score_unavailable_reasonPopulated only when the score is null, naming the layers that did not answer
metro_score_coverageWhich layers were available to score this metro. The denominator ships with the number
metro_sources_queried / metro_sources_failedEvery source queried, and any that did not answer
metro_enrichment_complete / metro_partial_runWhether every source for this metro answered
metro_min_signals_requested / metro_min_signals_appliedThe threshold asked for, and the one actually used
metro_min_signals_notePopulated only when the two differ, explaining why
metro_lookback_months / metro_window_start / metro_window_endThe window actually used
metro_data_vintagePer-source newest record date and age in days, measured on this run
metro_row_countsPer-source row counts for the window, including the Chicago negative control and the Detroit future-dated rows the bound excluded
metro_drift_measurementsEvery live drift measurement taken before any row was emitted
metro_owner_contact_rateShare of this metro's emitted rows carrying a deliverable mailing address, measured on this run rather than quoted
metro_candidate_countHow many properties met minSignals before ranking - the universe this row was selected from
metro_enrichment_pool_size / metro_enrichment_pool_capHow many candidates were owner-enriched, and the cap applied, so the selection method is visible rather than implied
metro_properties_with_any_signalHow many properties showed at least one signal in the window
implausible_date_rowsRows for this property whose source date fell outside 1990..today and was not trusted
implausible_date_rows_in_windowThe same count across the whole metro window
metro_source_urlsOpen-data pages for every source that contributed

The score is null, never lower, when a layer did not answer. A lower number would read as "less distressed" when it means "less known". The same rule applies to metro_score_coverage: a property scored in Detroit against four layers and one scored in Philadelphia against two do not mean the same thing, so the denominator is published alongside the number.

Live source checks that run before anything is billed

Every metro runs its gates first. If one fails, the run fails with an explanatory message and no row is emitted and nothing is billed - including rows from a metro that already succeeded, which are buffered and only pushed once every requested metro has passed.

CheckMeasured live 2026-08-06
Detroit blight tickets, total897,472
Detroit property_owner_name populated99.9998%
Detroit parcel roll, total377,863
Detroit taxpayer_address populated99.99%
Detroit newest ticket date (bounded)2026-08-06
Philadelphia violations, total / open2,002,359 / 89,045
Philadelphia opa_owner populated on open98.07%
Philadelphia OPA parcels583,700
Philadelphia newest violation date2026-08-05
Chicago building violations, total2,021,485
Chicago exact Vacant/Abandoned Building Complaint45,472
Chicago Clean Vacant Lot Request (negative control)38,911
Chicago scofflaw listings / newest list date659 / 2026-03-01
Cook County parcel universe max(year)2023

The Chicago pair is a discriminating control, not a floor: the exact sr_type match and the lot-mowing type are counted separately on every run. If the filter ever collapsed to a LIKE '%Vacant%' the two counts would converge, and the lead count would be inflated by 85.6% with requests to mow an empty lot. Detroit's newest-ticket check is measured against a closed upper bound because real rows carry year typos as far out as 8535; the rows the bound excluded are counted and published rather than dropped silently.

What v1.3 added (2026-08-06)

Detroit, Philadelphia and Chicago, from keyless government sources, with the owner contact taken from whatever each city actually publishes.

  • Nothing about New York changed. No field was removed, renamed or re-meaned, metros defaults to ["nyc"], and the New York code path is the v1.2 path untouched.
  • The owner contact is not inferred. Detroit and Philadelphia publish it on the violation record; Chicago is matched to the Cook County roll on an exact address and nothing else. Where a match fails, owner_lookup_status reads no_match, which is a measurement, not an outage.
  • Every source count is reconciled against the count the source itself reports before any row is ranked. A short read raises instead of ranking an arbitrary subset.
  • Tax delinquency was investigated and deliberately excluded in all three metros. See "What is deliberately NOT here" above.

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 is callable directly by any MCP-compatible AI agent through Apify's hosted MCP server. There is no server to run and no integration code to write - the tool schema an agent sees is generated from this Actor's own input and dataset schemas.

Endpoint

https://mcp.apify.com?tools=malonestar/distressed-property-signal-stacker

Claude Desktop, Claude Code or Cursor - add to claude_desktop_config.json, .mcp.json or .cursor/mcp.json respectively:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=malonestar/distressed-property-signal-stacker",
"headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
}
}
}

Get a token at https://console.apify.com/settings/integrations. Claude Desktop can also authenticate interactively via OAuth against https://mcp.apify.com with no headers block. Full reference: https://docs.apify.com/platform/integrations/mcp

Try asking your agent

Find me 100 Detroit properties with at least two distress signals and give me the owner name and mailing address for each.

Chains well with - expose these alongside it by comma-separating the tools parameter, and the agent can carry results from one into the next:

  • malonestar/parcel-owner-lookup
  • malonestar/acris-deed-transfer-intel
  • malonestar/absentee-owner-lead-list-builder
https://mcp.apify.com?tools=malonestar/distressed-property-signal-stacker,malonestar/parcel-owner-lookup,malonestar/acris-deed-transfer-intel,malonestar/absentee-owner-lead-list-builder

Billing is unchanged when called as an MCP tool: this Actor is Pay-Per-Event and an agent pays the same per-result price a human does. A run that cannot answer fails without billing rather than returning an unverified negative.

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.

ActorWhat it addsWhere
Absentee Owner Lead List BuilderOut-of-state and entity owners straight off the assessor roll, before any violation existsCook County (Chicago), Philadelphia, NYC
Parcel Owner LookupAddress to owner of record for one-off checks, with an explicit match-confidence on every answerCook County (Chicago), Philadelphia, NYC
NYC Landlord Registry Lead ListThe owner's whole portfolio - filter to landlords holding 5-50 buildings, with business contactNYC
NYC ACRIS Deed Transfer IntelWho actually bought and sold - deed price, LLC-buyer, cash-sale and out-of-state-buyer flagsNYC

Typical play: score distress here, then pull the owner's full portfolio to see whether this is a one-off or a landlord under pressure across many buildings. In Chicago and Philadelphia the assessor-roll actors above share the same parcel keys this actor emits (cook_pin, phila_opa), so the two stack directly.