HUD QCT LIHTC Boost Screener — 130% Basis by Coordinate avatar

HUD QCT LIHTC Boost Screener — 130% Basis by Coordinate

Pricing

from $3.30 / 1,000 results

Go to Apify Store
HUD QCT LIHTC Boost Screener — 130% Basis by Coordinate

HUD QCT LIHTC Boost Screener — 130% Basis by Coordinate

Qualified Census Tract (QCT) lookup for any coordinate — instantly flag the LIHTC 130% eligible-basis boost per site. Batch lat/lon points against HUD's official QCT layer; each returns in_qct, the 11-digit tract GEOID, state, county FIPS, tract, QCT vintage, and boost-eligible flag. MCP-ready.

Pricing

from $3.30 / 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

11 days ago

Last modified

Share

HUD QCT + DDA Screener - LIHTC 130% Basis Boost

Batch-screen coordinates against the two HUD designations that grant the 130% eligible-basis boost for Low-Income Housing Tax Credit deals under IRC Sec. 42(d)(5)(B): a Qualified Census Tract (QCT) and a Difficult Development Area (DDA). One clean row per site, with the designation vintage stamped on every row and a year-over-year comparison so you can see when a tract has been added or dropped.

Keyless. Three HUD.Official.Content ArcGIS services, queried live on every run:

SourceLayerLive count (2026-08-01)
QCT, current yearQUALIFIED_CENSUS_TRACTS_202614,496
QCT, prior yearQUALIFIED_CENSUS_TRACTS_202515,727
DDA, current yearDifficult_Development_Areas20262,902

What changed in v1.1 (2026-08-01), and why it matters to a tax position

v1.1 is a hardening release. Two of the changes fix answers that were materially wrong, both reproduced live. No output field was removed or renamed and the price is unchanged.

1. v1.0 was screening a superseded designation

v1.0 queried only HUD's 2025 QCT service while HUD publishes a 2026 one, and it stamped a hard-coded qct_year: "FY2025" constant that could never notice a new year had been published. QCT designations churn materially - Colorado went from 258 QCTs in 2025 to 224 in 2026: 49 tracts dropped, 15 added.

Worked example, in the prefill: Grand Junction, CO tract 08077000200 (39.07095, -108.55684) is a QCT in 2025 and not a QCT in 2026. v1.0 reported lihtc_130_basis_boost_eligible: true. v1.1 reports false, with in_qct_prior_year: true and qct_designation_change: "dropped_since_prior_year" so the prior-year answer is still there if you need it.

qct_year, qct_prior_year and dda_year are now derived at runtime from the live layer names, and a layer name that no longer parses fails the run rather than guessing.

2. v1.0 asserted "no boost" without ever checking DDA

lihtc_130_basis_boost_eligible mirrored in_qct alone. But the same 130% boost applies inside a Difficult Development Area, and the old code's claim that DDA "is not a point-queryable FeatureServer" is simply wrong - HUD publishes it as polygons.

Worked example, and it was the Actor's own control coordinate: Beverly Hills, CA (34.073, -118.400) sits inside the 2026 Small-Area DDA "Los Angeles-Long Beach-Glendale, CA HUD Metro FMR Area", ZCTA 90210. v1.0 reported lihtc_130_basis_boost_eligible: false. v1.1 reports true with basis_boost_basis: "dda".

3. A failed lookup can no longer read as "not eligible"

v1.0 initialised in_qct and lihtc_130_basis_boost_eligible to false in the base row. Every derived flag now starts null: null means not checked, false means checked and negative. Each row carries qct_status, qct_prior_status and dda_status, the boost flag is gated so it can never read false while a contributing source is unavailable, and if every source fails for every asset the run fails and bills nothing. The billing gate runs before any row is pushed.

4. Live drift assertions run before any billable row

Both QCT layers store Web Mercator, so a dropped inSR=4326 makes the service answer HTTP 200 with zero features - a false clear. Every run now proves: the layer names parse to a vintage and the "current" layer is not older than the "prior" one; national feature counts sit inside a measured band; DDA_TYPE contains only the closed vocabulary SA / NM; a positive QCT canary (South Bronx NY must resolve to tract 36005007900); a positive DDA canary (Beverly Hills must resolve to a Los Angeles DDA); and a negative control (an open-Pacific point must return exactly 0 from all three layers).


Who this is for

  • LIHTC developers and syndicators pre-qualifying a pipeline of sites for the 130% eligible-basis boost before ordering an appraisal or a market study.
  • Affordable-housing consultants and tax counsel who need the vintage on the record, because allocation and placed-in-service timing determine which year's designation applies.
  • State housing finance agencies and CDFIs batch-scoring applications.
  • Real-estate and site-selection teams layering the boost onto other constraints.
  • AI agents doing site due diligence - see the MCP note below.

Example input

{
"assets": [
{ "lat": 40.815, "lon": -73.904, "label": "South Bronx, NY (Qualified Census Tract)" },
{ "lat": 34.073, "lon": -118.4, "label": "Beverly Hills, CA (Small Area DDA - boost via DDA, not QCT)" },
{ "lat": 39.07095, "lon": -108.55684, "label": "Grand Junction, CO (QCT in the prior year, not the current one)" },
{ "lat": 39.0, "lon": -101.5, "label": "Rural Kansas (genuine clear - neither QCT nor DDA)" }
],
"maxAssets": 500
}

That is the prefilled input. Live on build 1.1.2 it returns four rows:

labelboost eligiblebasisin_qct (FY2026)prior (FY2025)changeDDA
South Bronx, NYtrueqcttrue (36005007900)trueqct_in_both_years-
Beverly Hills, CAtrueddafalsefalsenot_a_qct_in_either_yearLos Angeles-Long Beach-Glendale, CA HUD Metro FMR Area (SA, ZCTA 90210)
Grand Junction, COfalseneither_qct_nor_ddafalsetrue (08077000200)dropped_since_prior_year-
Rural Kansasfalseneither_qct_nor_ddafalsefalsenot_a_qct_in_either_year-

Rows two and three are exactly the answers v1.0 got wrong.

Input fields

FieldTypeRequiredDescription
assetsarrayyesPoints to screen. Each item: lat, lon (WGS84 decimal degrees), optional label. One billable row per asset.
maxAssetsintegernoSafety cap on how many assets are screened. Default 500, max 5,000.

Omitting assets returns HTTP 400 at run creation - the run never starts and nothing is billed.


Output fields

One row per screened asset. Every one of the 45 declared fields is listed here.

null on a flag always means the backing source did not answer, never the answer is no.

FieldTypeDescription
asset_labelstringnull
asset_latnumbernull
asset_lonnumbernull
in_qctbooleannull
tract_geoidstringnull
statestringnull
county_fipsstringnull
tractstringnull
qct_yearstringnull
lihtc_130_basis_boost_eligiblebooleannull
errorstringnull
source_urlstringnull
checked_atstringnull
qct_statusstringnull
qct_errorstringnull
qct_prior_statusstringnull
qct_prior_errorstringnull
dda_statusstringnull
dda_errorstringnull
sources_ok_countintegernull
sources_total_countintegernull
partial_resultbooleannull
qct_layer_namestringnull
qct_prior_yearstringnull
qct_prior_layer_namestringnull
dda_yearstringnull
dda_layer_namestringnull
in_qct_prior_yearbooleannull
tract_geoid_prior_yearstringnull
qct_designation_changestringnull
state_fipsstringnull
tract_namestringnull
in_ddabooleannull
dda_countintegernull
dda_typestringnull
dda_type_labelstringnull
dda_namestringnull
dda_codestringnull
dda_zcta5stringnull
basis_boost_basisstringnull
basis_boost_statutory_citationstringnull
disclaimerstringnull
source_url_qct_priorstringnull
source_url_ddastringnull
actor_versionstringnull

Fields that are legitimately null on a healthy run

A dead-column audit over the FULL dataset of a live run with the schema prefill (build 1.1.2) leaves exactly four fields null: qct_error, qct_prior_error, dda_error and error. All four being null is good news - it means every source answered. Each is pinned by a fault-injection fixture in offline.test.js, and each populates on any run during an upstream outage.

dda_* detail fields are null when the site is not in a DDA, and tract_geoid is null when it is not in a current-year QCT; the prefill deliberately includes one of each so every column populates on an auto-QA run.


Use as an MCP tool

This Actor is available to AI agents through mcp.apify.com. It is a good chainable tool because it takes plain coordinates and returns a flat, self-describing row: lihtc_130_basis_boost_eligible for the yes/no, basis_boost_basis for which designation carried it, qct_year / dda_year for the vintage, and qct_status / dda_status so an agent can tell a verified negative from an unanswered one.

Pricing

$6 per 1,000 results (pay-per-event, one Result event per screened asset). Graduated discounts apply on paid Apify plans. There are no other charge events.

Billing honesty: if every asset fails against every source the run fails and emits nothing, so you are not billed for an outage.

FAQ

Does lihtc_130_basis_boost_eligible: false mean there is definitely no boost? No. It means the site is in neither a current-year QCT nor a current-year DDA. State allocating agencies may still grant a discretionary basis boost under IRC Sec. 42(d)(5)(B)(v) for buildings that need it for financial feasibility, and that is a QAP decision this screen cannot see.

Which year applies to my deal? That depends on allocation and placed-in-service timing, and it is a question for your tax counsel. This Actor gives you both years - in_qct with qct_year, and in_qct_prior_year with qct_prior_year - plus qct_designation_change so you can see immediately when a site sits on the boundary between them.

Why does a site show in_qct: false but in_qct_prior_year: true? Because HUD re-designates QCTs annually against updated income and poverty data. Colorado lost 49 tracts and gained 15 between 2025 and 2026. qct_designation_change reads dropped_since_prior_year.

What is the difference between an SA and an NM DDA? SA is a Small-Area (metropolitan) DDA, designated by ZIP Code Tabulation Area - dda_zcta5 is populated. NM is a Non-Metropolitan DDA, designated by county - dda_zcta5 is null there, which is the source's own convention and not a missing value.

Why did my run fail with "LIVE DRIFT CHECK FAILED"? Because HUD's services no longer match what this Actor was verified against - a renamed or re-vintaged layer, a new DDA_TYPE code, or a canary that stopped returning known-good data. A loud failure is the correct answer: the alternative is a plausible tax screen computed from a source that has silently changed. Nothing is billed on a failed run.

Is this tax advice? No. It is an informational screen against public HUD data. Confirm against HUD's official QCT/DDA datasets at huduser.gov/portal/datasets/qct.html and with your tax-credit counsel.

  • HUD Affordable Housing Explorer - LIHTC, multifamily and public-housing inventory, plus Opportunity Zone point-in-polygon.
  • CDFI NMTC Low-Income & Energy Bonus Screener - the NMTC and IRA energy-community bonus-credit designations for the same coordinate.
  • FEMA NRI County Risk Profile and Site Due Diligence Bundle - the physical constraints that sit alongside the financial ones.

Informational screening tool built on public HUD data. Not tax advice, and not a HUD or IRS determination. Designations are re-published annually - always check the qct_year and dda_year on the row. Confirm with HUD and your tax-credit counsel before relying on the 130% basis boost.