HUD Section 8 Contract Expiration Monitor + Owner Contacts avatar

HUD Section 8 Contract Expiration Monitor + Owner Contacts

Pricing

from $6.60 / 1,000 contract rows

Go to Apify Store
HUD Section 8 Contract Expiration Monitor + Owner Contacts

HUD Section 8 Contract Expiration Monitor + Owner Contacts

Every HUD project-based Section 8, 202 and 811 HAP contract with its true term end (not the funding increment), assisted units, rent-vs-FMR position, owner and management-agent contacts, and a new-since-last-run delta.

Pricing

from $6.60 / 1,000 contract rows

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

Every HUD project-based Section 8, 202 and 811 HAP contract in the United States, with the date the contract term actually ends, assisted units, rent-vs-FMR position, owner and management-agent contacts, and a new-since-last-run delta.

Sourced live on every run from HUD's two published Multifamily files — 24,315 contracts covering 1,483,851 assisted units across 23,612 properties (measured 2026-08-17 on the 2026-08-11 vintage).

Who it is for

  • Affordable-housing acquirers and preservation developers — find the contracts that genuinely come up for renewal in your window, with the owner's name, mailing address, phone and email already on the row.
  • LIHTC syndicators and Year-15 buyers — screen Section 202/811 and older Section 8 stock by term end, rent position and Opportunity Zone status.
  • Lenders and mortgage bankers — size the HAP-expiry exposure in a market before underwriting.
  • Housing policy researchers and state housing agencies — build an honest expiring- contract pipeline instead of one inflated roughly four-fold.

The thing this actor exists to get right

HUD publishes two expiration dates and the obvious one is not the contract term end.

HUD columnWhat it actually is24-month screen (from 2026-08-18)
tracs_overall_expiration_dateContract term end — the genuine renewal / opt-out decision point4,627 contracts / 126,711 units
tracs_current_expiration_dateEnd of the current funding increment — routine annual funding18,939 contracts / 1,184,903 units

That is 4.09x the contracts and 9.35x the assisted units for the same window. The evidence that the overall column is the term end: tracs_effective_date plus contract_term_months_qty lands on it for 22,580 of 24,315 contracts (92.9%) and on the current column for only 8,483 (34.9%).

The clearest single case is Starrett City in Brooklyn, the largest project-based Section 8 contract in the country at 3,569 assisted units. Its current funding increment ends 2027-01-31. Its contract term runs to 2041-01-31. Screening on the increment column tells an acquirer that a 3,569-unit HAP contract expires in five months when it has fifteen years left.

This actor defaults to expirationBasis: "overall" and ships both dates on every row, labelled — contract_term_end_date and current_funding_increment_end_date — along with expiration_dates_differ, expiration_gap_days and term_end_reconciles_with_effective_plus_term so you can see the reasoning rather than trust it. Set expirationBasis: "current" if you specifically want the funding-increment calendar; nothing is hidden from you either way.

Example input

{
"states": ["CA"],
"expirationBasis": "overall",
"expiringWithinMonths": 36,
"contractStatuses": ["Active"],
"maxResults": 300
}

Other useful shapes:

{ "contractNumbers": ["NY36M000277"] }
{ "states": ["TX", "OK"], "expiringFiscalYears": ["2027", "2028"], "minAssistedUnits": 50 }
{ "ownerSearch": "Fairstead", "expirationBasis": "either", "expiringWithinMonths": 60 }
{ "states": ["OH"], "deltaOnly": true }

What it will refuse to do

This actor never returns a green empty run in place of an answer it could not compute.

  • No scope ({}) — fails immediately rather than dumping and billing all 24,315 contracts.
  • An unparseable filter — a three-letter state code, a non-numeric property id, an unknown expirationBasis — fails and names the field. It is never silently dropped.
  • Either HUD file unreachable or unparseable — fails. The properties file is where state, county, MSA, owner and management-agent contacts come from, so a run without it would publish nulls that read as verified absences.
  • HUD's data no longer matching the contract this actor was tested against — fails, with the specific measurement that moved.

Every failure message ends "Nothing was emitted and nothing was billed."

A query that is well-formed, reaches HUD, and genuinely matches nothing returns 0 rows and SUCCEEDS. That is the answer.

The live drift gate

Before a single row is buffered — and long before anything is pushed or billed — every run re-measures HUD's files against the properties this actor was built on. All of these are logged on every run, so a future tightening can be evidence-based:

CheckLive value 2026-08-17Fails at
Contract row count24,315below 20,000
Property row count23,612below 20,000
Contract-to-property join coverage100.00%below 95%
HUD's published fiscal year vs the one derived from the term-end date100.00%below 99%
Term end later than funding-increment end63.18%below 20%
Positive canary NY36M000277 (Starrett City)3,569 units, NY, term 2041-01-31 > increment 2027-01-31any mismatch
Negative control ZZ00X0000000 matchesany match
Unrecognised status / doc type / program group0.00%above 5%
File vintage age6 daysabove 400 days

The fifth row is the product premise: if HUD ever collapses the two expiration columns into one meaning, "contract term end" stops being separable from "current funding increment end" and this actor fails loudly rather than publishing the wrong pipeline.

New-since-last-run delta

deltaOnly: true returns only contracts that are new, or whose term end, funding increment end, assisted units or status moved since the previous run.

Two things this deliberately does not do:

  • The baseline lives in a named key-value store, not the per-run default store. A per-run store would make every contract read "new" on every run, forever, and bill the full file as a delta.
  • The baseline is always the full national universe, never the filtered subset. A California-scoped run cannot make the next Texas-scoped run report everything as new.

On the very first run there is no baseline, so is_new_since_last_run is null, not true — "we have never seen this file" is not the same claim as "this contract is new". delta_status reads baseline_established.

Data quality decisions you can audit

Every one of these was measured on the live file, and each is visible on the row rather than resolved silently.

  • rent_to_FMR_ratio = 0 is a null sentinel, carried by exactly the 334 contracts whose rent_to_FMR_description reads "Unknown". Reading those zeros as real would rank them as the deepest below-FMR contracts in America — the most attractive preservation targets — off data HUD never published. rent_to_fmr_pct is null there and rent_to_fmr_basis says zero_sentinel_not_published.
  • msa_code = "9999" is an undocumented second sentinel on 6,489 of 23,612 properties (27.5%), with a null MSA name, carried by properties plainly inside metro areas including Starrett City in Brooklyn. "0000" is HUD's documented "Not In Metro Area" (681 properties). Both are suppressed from msa_code and preserved in msa_code_raw with msa_sentinel_meaning.
  • State comes from the property record, never the contract number. The first two characters of a contract number look like a state code but disagree with the property's own state_code on 229 of 24,315 contracts (0.94%) — the territories use a separate vocabulary (RQ for PR ×196, VQ for VI ×19, TQ for MP ×4, GQ for GU ×1) and nine contracts are genuinely cross-border (OR→WA ×6, MD→DC, LA→MS, RQ→VI). Both values ship, with state_prefix_matches_property_state.
  • A bedroom-size FMR of 0 alongside a non-zero unit count of that size is missing, not $0 (680 contracts).
  • A participant id of 0 is a null sentinel, not participant zero (37 owner rows, 82 agent rows).
  • HUD uses three different blank conventions in one pair of files — whitespace padding on the property block, a single space on the owner/agent block, an empty string on associated_financing_Number and ownership_effective_date. All become null.
  • The properties sheet ends with three entirely blank rows inside its declared range. They are dropped rather than emitted as three all-null properties.
  • Four contracts publish a funding increment ending after the contract term, and one publishes no current expiration at all. Flagged via expiration_dates_inconsistent, never normalised away.
  • 70 properties have contract assisted units exceeding HUD's own total unit count. Flagged via assisted_units_exceed_property_total, never clamped.
  • The data vintage is read from the Last-Modified header on every run and published on every row. HUD replaces these files in place, so the vintage cannot be inferred from the URL.

Use as an MCP tool

This actor is callable by AI agents over Apify's hosted MCP endpoint. Add it to a client config:

{
"mcpServers": {
"apify": {
"command": "npx",
"args": ["-y", "@apify/actors-mcp-server", "--actors", "malonestar/hud-section8-contract-expiration-monitor"],
"env": { "APIFY_TOKEN": "your-apify-token" }
}
}
}

A worked agent prompt: "List every HUD Section 8 contract in Ohio whose contract term ends in federal fiscal year 2028, with at least 100 assisted units, and give me the owner's email and phone for each."

Billing is unchanged when called as a tool: one dataset row is one billable result, and a run that cannot answer fails without billing.

  • hud-affordable-housing-explorer — LIHTC, multifamily and public-housing inventory with Opportunity Zone overlay.
  • hud-qct-lihtc-boost-screener — Qualified Census Tract and 130% basis-boost eligibility.
  • fema-nri-county-risk-profile — county and tract natural-hazard risk for the same assets.

Output fields

All 148 fields are documented here and declared in the dataset schema. Every field is nullable unless it is structurally always present. null means not checked; false means checked and negative. The two are never collapsed.

FieldTypeDescription
contract_numberstringnull
property_idintegernull
property_namestringnull
contract_statusstringnull
contract_status_is_activebooleannull
contract_status_vocabulary_knownbooleannull
contract_doc_type_codestringnull
program_type_namestringnull
program_type_group_codestringnull
program_type_group_namestringnull
is_hud_administeredbooleannull
is_old_accbooleannull
is_performance_based_accbooleannull
assisted_unitsintegernull
units_0brintegernull
units_1brintegernull
units_2brintegernull
units_3brintegernull
units_4brintegernull
units_5plus_brintegernull
bedroom_counts_reconcile_with_assisted_unitsbooleannull
expiration_basis_usedstringnull
expiration_date_usedstringnull
months_to_expiration_usedintegernull
contract_effective_datestringnull
contract_term_monthsintegernull
contract_term_end_datestringnull
contract_term_end_fiscal_yearintegernull
contract_term_end_fiscal_quarterstringnull
contract_term_end_fiscal_year_derivedintegernull
current_funding_increment_end_datestringnull
current_increment_end_fiscal_yearintegernull
current_increment_end_fiscal_quarterstringnull
tracs_overall_expiration_serial_rawintegernull
tracs_current_expiration_serial_rawintegernull
expiration_dates_differbooleannull
expiration_gap_daysintegernull
expiration_dates_inconsistentbooleannull
term_end_reconciles_with_effective_plus_termbooleannull
days_to_term_endintegernull
days_to_current_increment_endintegernull
term_end_is_pastbooleannull
current_increment_end_is_pastbooleannull
rent_to_fmr_pctnumbernull
rent_to_fmr_bandstringnull
rent_to_fmr_basisstringnull
rent_above_fmrbooleannull
rent_at_or_below_80pct_fmrbooleannull
fmr_0brintegernull
fmr_1brintegernull
fmr_2brintegernull
fmr_3brintegernull
fmr_4brintegernull
property_join_statusstringnull
hub_namestringnull
servicing_site_namestringnull
property_address_line1stringnull
property_address_line2stringnull
property_citystringnull
property_state_codestringnull
property_zip_codestringnull
property_zip4_codestringnull
state_from_contract_number_prefixstringnull
state_prefix_matches_property_statebooleannull
county_codestringnull
county_namestringnull
msa_codestringnull
msa_code_rawstringnull
msa_namestringnull
msa_code_is_sentinelbooleannull
msa_sentinel_meaningstringnull
congressional_district_codestringnull
placed_base_city_namestringnull
property_phonestringnull
property_phone_digitsstringnull
property_total_unitsintegernull
assisted_unit_share_pctnumbernull
assisted_units_exceed_property_totalbooleannull
property_categorystringnull
primary_financing_typestringnull
associated_financing_numberstringnull
ownership_effective_datestringnull
is_insuredbooleannull
is_202_or_811booleannull
is_hud_heldbooleannull
is_hud_ownedbooleannull
is_hospitalbooleannull
is_nursing_homebooleannull
is_board_and_carebooleannull
is_assisted_livingbooleannull
is_refinancedbooleannull
is_section_221d3booleannull
is_section_221d4booleannull
is_section_236booleannull
is_non_insuredbooleannull
is_bmirbooleannull
is_risk_sharingbooleannull
is_mipbooleannull
is_co_insuredbooleannull
is_opportunity_zonebooleannull
owner_contact_statusstringnull
owner_participant_idintegernull
owner_company_typestringnull
owner_organization_namestringnull
owner_individual_full_namestringnull
owner_individual_titlestringnull
owner_address_line1stringnull
owner_address_line2stringnull
owner_citystringnull
owner_state_codestringnull
owner_zip_codestringnull
owner_zip4_codestringnull
owner_phonestringnull
owner_phone_digitsstringnull
owner_faxstringnull
owner_emailstringnull
mgmt_agent_contact_statusstringnull
mgmt_agent_participant_idintegernull
mgmt_agent_company_typestringnull
mgmt_agent_org_namestringnull
mgmt_agent_individual_full_namestringnull
mgmt_agent_individual_titlestringnull
mgmt_agent_address_line1stringnull
mgmt_agent_address_line2stringnull
mgmt_agent_citystringnull
mgmt_agent_state_codestringnull
mgmt_agent_zip_codestringnull
mgmt_agent_zip4_codestringnull
mgmt_agent_phonestringnull
mgmt_agent_phone_digitsstringnull
mgmt_agent_faxstringnull
mgmt_agent_emailstringnull
owner_is_own_management_agentbooleannull
delta_statusstringnull
is_new_since_last_runbooleannull
delta_changed_fieldsarraynull
delta_previous_valuesobjectnull
baseline_built_atstringnull
baseline_contract_countintegernull
contracts_data_vintagestringnull
properties_data_vintagestringnull
contracts_source_statusstringnull
properties_source_statusstringnull
retrieved_atstringnull
matched_rows_totalintegernull
results_truncatedbooleannull
max_results_appliedintegernull
expiration_basis_requestedstringnull

Source

  • https://www.hud.gov/sites/dfiles/Housing/documents/MF-Assistance-Sec8-Contracts1.xlsx (24,315 contracts x 31 columns)
  • https://www.hud.gov/sites/dfiles/Housing/documents/MF-Properties-with-Assistance-Sec8-Contracts1.xlsx (23,612 properties x 74 columns)

Both are public, keyless, and joined on property_id. Vintage 2026-08-11 as measured 2026-08-17; HUD republishes roughly monthly and replaces the files in place.

FAQ

When does a HUD Section 8 contract actually expire? On its contract term end (contract_term_end_date). The current funding increment end is a routine annual funding action, not the renewal decision.

Can I get the owner's email and phone? Yes. Owner email is populated on 23,459 of 23,612 properties (99.35%) and the management agent email on 23,426 (99.21%), across 11,151 and 10,374 distinct addresses respectively. Owner mailing address, phone and company type ship too, plus owner_contact_status so a partial record is visible.

How do I find expiring Section 8 contracts in my state?

{"states":["CA"], "expiringWithinMonths":36,"contractStatuses":["Active"]}
.

How do I monitor for new or amended contracts? Schedule the actor and set deltaOnly: true. The first run establishes a full-universe baseline and reports baseline_established; subsequent runs report only what moved.

Which contracts have rents below FMR? Filter on rent_at_or_below_80pct_fmr or sort by rent_to_fmr_pct. Rows where HUD published no rent position carry null, not 0, so they cannot masquerade as deep discounts.

Does this cover Section 202 and 811? Yes: 5,687 PRAC 202/811 contracts, 3,894 Section 202, 953 811 PRA Demo and 121 PAC 202/811, alongside the Section 8 stock.