HUD Affordable Housing Explorer: LIHTC + Multifamily + Public avatar

HUD Affordable Housing Explorer: LIHTC + Multifamily + Public

Pricing

from $3.30 / 1,000 results

Go to Apify Store
HUD Affordable Housing Explorer: LIHTC + Multifamily + Public

HUD Affordable Housing Explorer: LIHTC + Multifamily + Public

Search HUD LIHTC, FHA-insured multifamily, and public housing layers as one unified property feed. Filter by state, city, program, and minimum units; each row has units, low-income units, owner/manager, lat/lon, and an Opportunity Zone flag. Lead lists for LIHTC investors, developers, lenders.

Pricing

from $3.30 / 1,000 results

Rating

0.0

(0)

Developer

Kyle Maloney

Kyle Maloney

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

4 days ago

Last modified

Share

HUD Affordable Housing Explorer — LIHTC, Multifamily, Public Housing + Opportunity Zones

One unified property list across three HUD programs at once, with a designated Qualified Opportunity Zone flag computed by point-in-polygon. Keyless, straight from HUD's own eGIS ArcGIS services.

ProgramWhat it isLive count
LIHTCLow-Income Housing Tax Credit properties50,566
HUD_INSUREDFHA-insured multifamily properties17,582
PUBLIC_HOUSINGPublic housing developments6,211
Opportunity ZonesTreasury-designated QOZ census tracts8,765

Counts measured live on 2026-08-01 and re-measured on every run — see data_vintage.

What makes this different

  • Three programs, one row shape. LIHTC, FHA-insured multifamily and public housing normally live in three incompatible datasets. Here they share a single schema, so a portfolio screen is one query.
  • Nothing is asserted that was not checked. opportunity_zone is three-valued: true, false, or null when it could not be tested. Every row names which HUD layers answered (lihtc_status, hud_insured_status, public_housing_status) and whether the result set is complete (result_complete).
  • Truncation is disclosed, not silent. Every row carries records_available_in_scope — the exact number of records your filter matched — next to records_returned and results_truncated.
  • HUD republishes these layers annually. Before anything is billed, the run asserts each layer's name, its column set and its record count against values measured live, plus a positive canary and a negative control on the QOZ layer. If HUD swaps a layer for a different vintage, the run fails loudly instead of quietly answering from stale designations.

Who this is for

  • Affordable-housing developers and syndicators — comparable LIHTC deals in a market, with allocation amount, credit type, bond financing, QCT/DDA basis boost and unit mix.
  • CRE acquisition teams — FHA-insured multifamily with REAC inspection scores, loan maturity, watch-list and default flags.
  • Housing policy and research — subsidised stock per state or city with resident demographics and occupancy.
  • Opportunity Zone investors — properties inside designated QOZ tracts, with the tract GEOID and Treasury rural flag.
  • AI agents — one call per state; three-valued flags and per-layer status so the agent can tell "no" from "not checked".

Example input

{
"states": ["CO"],
"programs": ["LIHTC", "HUD_INSURED", "PUBLIC_HOUSING"],
"city": "",
"minUnits": 0,
"includeOpportunityZoneFlag": true,
"onlyOpportunityZone": false,
"maxResults": 500
}

city matches as a prefix, case-insensitively. minUnits and onlyOpportunityZone are applied after fetching, so the run pulls a buffer beyond maxResults when either is set.

Output — every field

The property

FieldMeaning
programLIHTC, HUD_INSURED, or PUBLIC_HOUSING.
source_idHUD's own identifier: LIHTC HUD_ID, FHA property ID, or public-housing development code.
property_nameProject or property name.
address, city, state, zip, countyLocation as HUD publishes it.
standardized_addressHUD's USPS-standardized street address.
census_tract_geoid11-digit census tract GEOID from HUD's own geocoding columns.
msa_name, cbsa_nameMetro area.
latitude, longitudeWGS84 coordinate, where HUD publishes one.
units_totalTotal units.
units_low_incomeIncome-restricted / assisted units.
units_occupied, units_vacant, occupancy_pctOccupancy detail.
unit_mixBedroom mix (LIHTC in counts, Public Housing in percentages).
year_placed_in_serviceYear the property entered service.
owner_or_managerOwner or management agent. HUD leaves the LIHTC COMPANY column empty for all 50,566 LIHTC properties nationwide, so this is populated on HUD Insured and Public Housing rows only — use contact_name for LIHTC.
contact_name, contact_phone, contact_emailPublished contact for the property.
program_detailFree-text program summary.

Opportunity Zone

FieldMeaning
opportunity_zoneThree-valued. true = inside a designated QOZ tract. false = tested against the loaded QOZ layer and outside one. null = NOT tested.
opportunity_zone_statusWhy: ok, unavailable (the layer did not answer), no_polygons_returned, no_coordinate_published (HUD publishes no lat/lon for this property), or not_requested.
oz_tract_geoidGEOID10 of the QOZ tract.
oz_is_ruralTreasury rural flag on that tract.

LIHTC detail

FieldMeaning
year_allocatedYear the tax credits were allocated (distinct from placed-in-service).
allocation_amount_usdAnnual credit allocation.
is_bond_financedTax-exempt bond financed, i.e. the 4% credit rather than the competitive 9%.
credit_typeHUD's credit-type code.
construction_typeNew construction, acquisition and rehab, or both.
nonprofit_sponsorA nonprofit is the project sponsor.
target_populationFamily, Elderly, Disabled, Homeless.
in_qualified_census_tractIn a HUD Qualified Census Tract (30% basis boost).
in_difficult_development_areaIn a HUD Difficult Development Area (30% basis boost).

HUD Insured Multifamily detail

FieldMeaning
reac_last_inspection_scoreMost recent REAC physical-inspection score, 0-100. Below 60 triggers HUD enforcement.
reac_last_inspection_dateDate of that inspection.
has_section_8Active Section 8 contract.
is_subsidizedCarries HUD subsidy.
is_section_202_811Section 202 (elderly) or Section 811 (disabled).
is_in_defaultThe FHA-insured mortgage is in default or delinquent.
on_watch_listHUD has placed the property on its watch list.
loan_maturity_dateMaturity of the insured mortgage.
original_loan_amount_usdOriginal insured mortgage amount.
contract_expiration_dateWhen the primary HUD assistance contract expires — the date the affordability restriction can lapse. Populated on 4,903 of 17,582 properties.

Public Housing detail

FieldMeaning
pha_codePublic Housing Authority participant code.
pha_total_unitsTotal units that PHA operates.
scattered_siteA scattered-site development rather than a single building.

Residents

FieldMeaning
pct_elderlyResidents aged 62+.
pct_disabledResidents reported with a disability.
pct_minorityResidents reported as a racial or ethnic minority.
avg_household_income_usdAverage annual household income.
avg_rent_per_month_usdAverage monthly tenant-paid rent.

Provenance — read these before trusting a result set

FieldMeaning
lihtc_status, hud_insured_status, public_housing_statusPer-layer outcome: ok, partial, unavailable, or null (not requested).
programs_queriedEvery program this run should have consulted.
programs_okThe ones that answered.
programs_failedThe ones that did not. null when all answered.
result_completetrue only when every requested layer answered.
records_available_in_scopeExact count matching your state/city filter, before minUnits / onlyOpportunityZone and before maxResults.
records_returnedRows actually returned.
results_truncatedtrue when fewer rows came back than matched the scope.
data_vintageThe record and column counts measured on each HUD layer at run time. A change between runs means HUD republished a layer.
checked_atUTC ISO-8601 timestamp of the run.

Inputs that populate the sparser columns

ColumnsVerified live input
contract_expiration_date{"states":["NY"],"programs":["HUD_INSURED"],"maxResults":500} — HUD publishes it on 4,903 of 17,582 properties (281 in NY, 47 in CO).
reac_last_inspection_score, loan_maturity_date, has_section_8, contact_emailAny run including HUD_INSURED.
in_qualified_census_tract, allocation_amount_usd, unit_mixAny run including LIHTC.
pha_code, units_occupied, scattered_siteAny run including PUBLIC_HOUSING.
programs_failedPopulated only when a HUD layer fails. null on a healthy run is the good outcome.

How it works

  1. Live drift assertions run first, before anything billable. Each layer's name, column set and record count is checked against values measured on 2026-08-01, and the QOZ layer additionally gets a positive canary and a negative control (a state code that must match nothing — this catches a silently-ignored filter). Any failure fails the run and bills nothing.
  2. Each program is queried separately with an exact returnCountOnly count so truncation can be disclosed, then paged.
  3. The program groups are round-robin merged so a capped run stays representative of every program rather than being monopolised by LIHTC, which has the most rows.
  4. Designated QOZ tract polygons for the selected states are loaded and each property is tested by point-in-polygon. If the layer did not answer, or HUD publishes no coordinate for a property, opportunity_zone is null.
  5. Filters are applied, results capped, and the billing gate runs before anything is written. If every layer failed, or nothing matched, the run fails with a message naming the cause.

Use as an MCP tool

Available through mcp.apify.com. One call per state. An agent should treat opportunity_zone: null as unknown (never as "not in an Opportunity Zone"), and check result_complete before concluding a market has no assisted housing.

Pricing

Pay-per-result: one property row = one billed result. A failed run emits nothing and costs nothing beyond the platform's Actor-start event. Volume tiers apply automatically on paid Apify plans.

FAQ

Why is owner_or_manager empty on LIHTC rows? Because HUD leaves the COMPANY column empty for every one of the 50,566 LIHTC properties it publishes — verified live. contact_name and contact_phone carry the LIHTC allocation contact instead.

Why is opportunity_zone null on some rows? Because the property could not be tested — usually because HUD publishes no coordinate for it. Read opportunity_zone_status. A null is not a negative finding.

Why did the run fail instead of returning zero rows? Because a zero that comes from a failed layer, an over-tight filter or an outage is indistinguishable from a genuine "no such housing here". The failure message names the cause and nothing is billed.

How do I get everything in a state? Raise maxResults. Compare records_returned with records_available_in_scope to see what you are missing.

Is the Opportunity Zone flag legal advice? No. It is a point-in-polygon screen against HUD's published QOZ tract layer. Confirm with the tract's official designation before relying on it.

  • hud-qct-lihtc-boost-screener — Qualified Census Tract / DDA basis-boost check for an arbitrary coordinate.
  • nyc-landlord-registry-lead-list, distressed-property-signal-stacker — owner contact and distress signals for NYC multifamily.
  • fdic-sod-deposit-market-share-rollup — the lending market around a metro.