Reference
A complete catalog of the label's thirteen dimensions, every variable you can control, and where each input comes from geographically. For the underlying formulas and sources, see Methodology; to run it yourself, see Setup.
Geographic resolution: what's measured where
Some inputs are pulled for your exact address; others describe the surrounding census tract or county; the grid-carbon factors describe a whole power-grid region; a couple use national models; and a few depend only on your house and are identical anywhere. This is the single most common source of confusion, so here it is up front.
| Resolution | What's resolved at this level |
|---|---|
| Address point | Flood zone (FEMA NFHL), seismic PGA (USGS) |
| Census tract | Tornado & wildfire expected annual loss (FEMA National Risk Index); Health (CDC PLACES), Socioeconomic (Census ACS), Walkability (EPA National Walkability Index), Air Quality PM2.5 + ozone (CDC Tracking), and Noise (US DOT BTS transportation-noise exposure), each scored against the national distribution of US tracts and comparable across locations |
| County | Energy climate zone (IECC), Infrastructure Burden (cost / property-tax model), the Air Quality radon layer (EPA Map of Radon Zones, a county-level dataset), Solar Potential (PVGIS rooftop specific yield), and Water Quality (EPA SDWIS community-water-system health-based violations), all scored against the national distribution of US counties |
| Grid region | Environmental grid-carbon factors (kg CO₂e/kWh). Your county only picks the region here — the factors themselves describe a multi-state power grid, so two counties hundreds of miles apart can share the same number. The grid average is the eGRID2023 Rev 2 subregion rate (~26 nationally; county→subregion crosswalk, US-average fallback) and the marginal rate, used to credit solar/efficiency-avoided kWh, is NREL Cambium 2023 LRMER (18 GEA regions, CONUS-only — outside that no marginal credit is applied) |
| Your house only | Durability, embodied carbon, and the fire peril: driven by construction / year / condition, identical at any location |
The dimensions
The engine scores thirteen dimensions. The composite is the mean of whichever could be scored (location dimensions are omitted, not zeroed, when their data/keys are unavailable). National grades use absolute thresholds: A ≥ 80, B ≥ 60, C ≥ 40, D ≥ 20, F < 20.
| Dimension | Measures | Data source | Resolution |
|---|---|---|---|
| Disaster Resilience | Expected annual loss from flood, tornado, earthquake & fire | FEMA NFHL, FEMA NRI, USGS, NFPA base rate | point tract + config |
| Energy Efficiency | Modeled energy use intensity vs. a ResStock building-type×climate-zone×vintage benchmark | NREL ResStock 2024 (building type×zone×vintage + foundation/HVAC factors) + IECC climate zone + construction model | county + config |
| Durability | Building longevity from materials, build quality & condition | Construction model | config |
| Environmental Footprint | Embodied + operational carbon over the building's life | Material carbon + eGRID2023 Rev 2 subregion grid average + NREL Cambium 2023 LRMER marginal factor | grid region + config |
| Infrastructure Burden | Fiscal cost-to-serve vs. the revenue the parcel generates | Census of Governments spending + ACS tax model (per county) | county |
| Health Impact | Neighborhood health outcomes (national percentile) | CDC PLACES | tract |
| Air Quality | Ambient PM2.5 + ozone & radon zone (national percentile) | CDC Tracking (PM2.5/ozone) + EPA radon zones | tract + county radon |
| Noise | Transportation-noise exposure: % of residents at ≥60 dB (national percentile), refined to the parcel when no highway, arterial or railroad is near enough for ≥60 dB to carry (Census TIGERweb). Aviation noise is not visible to that check | US DOT BTS National Transportation Noise Map | tract |
| Socioeconomic | Neighborhood socioeconomic index (national percentile) | Census ACS | tract |
| Walkability | How walkable the location is | EPA National Walkability Index | tract |
| Climate Projections | Projected extreme heat, heavy precip/flood, drought & fire weather (SSP2-4.5–SSP5-8.5, mid-century) | USGS CMIP6-LOCA2 (~6 km) + Argonne ClimRR fire weather | tract + county fallback |
| Solar Potential | Rooftop specific yield (kWh/kW·yr): production, $ saved & CO₂ avoided (national percentile), queried at the parcel rather than at the county's centroid; falls back to the county figure off-network or outside PVGIS-NSRDB coverage | PVGIS v5.2 on NREL NSRDB | point + county fallback |
| Water Quality | The serving water system's own health-based violation record — years out of compliance in the last five, ranked nationally. Falls back to county-wide exposure when SDWIS has no active record for the system. Left unscored for a home on a private well — SDWIS covers community systems only, so the county figure measures a population that household isn't part of. A parcel outside every mapped community service area is treated as a well unless the owner says otherwise | EPA SDWIS federal reporting; parcel → system via EPA ORD public water system service-area boundaries | water system + county fallback |
Wall / construction type
The structural system. It drives Disaster Resilience (separate factors per peril) and the build-quality grade used by Durability & Environmental. Lower peril factors = less expected loss = better; higher build grade = better. ICF/SIP also get extra envelope credit in the Energy model beyond what the wall code below implies.
| Type | Wind / seismic | Flood | Fire | Build grade | Notes |
|---|---|---|---|---|---|
| Wood frame | 1.20 | 1.20 | 1.10 | 38 | Light wood frame, the baseline; most vulnerable to wind/seismic |
| Vinyl-sided frame | 1.15 | 1.15 | 1.10 | 35 | Wood frame with vinyl siding: slight wind benefit, slightly lower build grade |
| Brick veneer / frame | 1.00 | 1.00 | 1.00 | 42 | Brick veneer over a wood frame, composite baseline |
| Brick (solid masonry) | 0.95 | 0.95 | 0.85 | 48 | Solid brick; better lateral resistance & less combustible |
| Concrete block (CMU) | 0.90 | 0.90 | 0.80 | 46 | Reinforced masonry; strong lateral resistance |
| Stone | 0.85 | 0.85 | 0.80 | 52 | Solid masonry; best of the traditional types |
| ICF (insulated concrete form) | 0.25 | 0.45 | 0.70 | 50 | Monolithic concrete shell; huge wind/seismic & fire benefit (finishes still flood-vulnerable) |
| SIP (structural insulated panel) | 0.35 | 0.35 | 1.05 | 45 | Engineered wood composite; excellent racking resistance, frame-like fire behavior |
| Steel frame / steel wall | 0.90 | 0.90 | 0.80 | 44 | Cold-formed or red-iron steel; non-combustible and rot-proof, but the studs bridge heat so the envelope costs more to condition |
Condition
Upkeep/deterioration. Multiplies expected loss for every disaster peril (so it affects the score at any age, with no upper cap) and feeds the Durability model.
| Condition | Loss multiplier |
|---|---|
| Unsound | 1.5× (worst) |
| Poor | 1.3× |
| Fair | 1.1× |
| Average | 1.0× (baseline) |
| Good | 0.9× |
| Excellent | 0.8× (best) |
Foundation
Affects the flood peril only (below-grade space is what floods).
| Foundation | Flood multiplier |
|---|---|
| Slab | 0.7× (at/above grade; least flood loss) |
| Crawl space | 1.0× (baseline) |
| Partial basement | 1.2× |
| Full basement | 1.4× (most flood loss) |
Year built
The build-code era (wind/seismic) vulnerability is a continuous curve, linearly interpolated between the anchor years below and clamped beyond them. A 1969 and a 1970 build no longer differ by a cliff. Lower is better.
| Anchor year | Code factor (wind/seismic) | Era |
|---|---|---|
| 1940 or earlier | 1.6× | Pre-WWII: balloon framing, no engineered connections |
| 1970 | 1.3× | Pre-modern seismic/wind codes (pre-1972 wind, pre-1971 seismic) |
| 1990 | 1.1× | Early modern (ASCE 7 wind), pre-Northridge detailing |
| 2003 | 1.0× | Baseline: IBC maturity / ASCE 7-02 |
| 2010 or later | 0.85× | Fully modern IBC / ASCE 7-05–7-10 |
A separate continuous curve captures the electrical/wiring era (fire peril), interpolated between these anchors and clamped beyond them.
| Anchor year | Fire factor | Wiring era |
|---|---|---|
| 1950 or earlier | 1.5× | Knob-and-tube era (highest electrical-fire risk) |
| 1975 | 1.2× | Aluminum branch-wiring era |
| 2002 | 1.0× | Modern NM-B cable, pre-AFCI baseline |
| 2010 or later | 0.85× | NEC 2002+ AFCI / tamper-resistant receptacles |
Other house fields
| Field | What it does | Default |
|---|---|---|
| Flood zone | FEMA zone (X minimal, X500 moderate, AE high). Auto-derived from the resolved location (address or lat/lon) via FEMA NFHL if not set. | auto (FEMA NFHL) |
| Value | Market value; scales the dollar-denominated expected loss (not the 0–100 scores, which are rates). | $160,000 |
| Units | Dwelling units; the parcel is framed per-unit for the construction dimensions. | 1 |
| Square footage | Living area of a single dwelling unit (per unit, not the whole building, so it is not divided by the unit count); feeds the energy & environmental per-area models. | 2,000 |
| Lot acres | Parcel size; feeds the infrastructure cost-to-serve model. | 0.25 |
Resilience upgrades
Above-code features that reduce a specific peril's expected loss. Each is a multiplier (lower = bigger reduction) applied on top of the construction/condition adjustment. FORTIFIED tiers are composite and supersede the individual wind features; the three elevation tiers are mutually exclusive.
General (apply to flood, tornado & seismic)
| Upgrade | Factor |
|---|---|
| Solar panels | no loss credit — grid-tied PV yields no outage power, and it earns its credit in energy & carbon instead |
| Backup generator / battery | no loss credit here — see the backup-powered sump pump under Flood |
| Passive-house certification | 0.92 |
| Fire sprinklers | no general credit — 0.45 on structural fire |
Wind / tornado
| Upgrade | Factor |
|---|---|
| Tornado safe room (FEMA P-361) | 0.85 |
| Hurricane straps (continuous load path) | 0.92 |
| Hip roof | 0.80 |
| Wind-rated garage door | 0.95 — rated for wind PRESSURE (ANSI/DASMA 108); garage doors fail by pressure, not debris |
| Sealed roof deck | 0.93 |
| Standing-seam metal roof | 0.75 |
| Reinforced gable ends | 0.98 |
| Ring-shank nails | 0.97 — credited only above the deck schedule the build year already assumes |
IBHS FORTIFIED (composite that supersedes the wind features above)
| Upgrade | Factor |
|---|---|
| FORTIFIED Roof | 0.35 |
| FORTIFIED Silver | 0.25 |
| FORTIFIED Gold | 0.20 |
Seismic
| Upgrade | Factor |
|---|---|
| Foundation anchorage retrofit (bolting) | 0.75 on non-slab foundations — superseded by cripple-wall bracing, which includes it |
| Cripple-wall bracing | 0.45 on raised foundations only (crawl or partial basement) — a slab has no cripple wall to brace |
| Seismic hold-downs | no separate credit — tie-downs are part of the cripple-wall retrofit, and in upper walls they mark engineered construction the build year covers |
| Automatic gas shut-off valve | 0.90 |
Flood
| Upgrade | Factor |
|---|---|
| Elevated +1 ft above BFE | 0.15 |
| Elevated +2 ft | 0.08 |
| Elevated +3 ft | 0.05 — also the floor on the whole flood stack, since this is a total residual rather than a partial credit |
| Engineered flood vents | 0.85 |
| Backflow-prevention valve | no credit — acts on sewer backup, which is outside the external flooding this leg scores |
| Backup-powered sump pump | 0.97 |
| Smart leak detection | no flood credit — mitigates plumbing-failure water damage, which is outside the four perils scored here |
Fire
| Upgrade | Factor |
|---|---|
| Fire sprinklers | 0.45 on the structural fire term (~55% loss reduction, NFPA 2024); not applied to the wildfire term |
Air quality
| Upgrade | Factor |
|---|---|
| Radon mitigation system | no resilience credit — radon is a chronic indoor-air hazard, not one of the four perils scored here. It acts on Air Quality instead, where EPA's “up to 99% reduction” floors the radon sub-score at the Zone 3 value |
Presets
Starting configurations. Any field you set in Construction details (or via CLI/API) overrides the preset.
| Preset | Profile |
|---|---|
| baseline | 2000 wood frame, slab, average, zone X, $160k |
| premium | 2026 solid brick, slab, excellent, zone X, $450k |
| icf-passive | 2026 ICF, slab, excellent, zone X, $500k · solar, generator, passive house, safe room, hurricane straps, hip roof, sealed roof deck, metal roof, +1 ft elevation |
| worst-case | 1945 wood frame, full basement, poor, zone AE, $80k |
| fortified-gold | 2026 wood frame, slab, excellent, zone X, $350k · sealed roof deck, metal roof, FORTIFIED Gold |
| duplex | 2026 solid brick, 2 units × 1,200 sqft, excellent, zone X, $300k |
| quadplex | 2026 solid brick, 4 units × 900 sqft, excellent, zone X, $500k |
| icf-quadplex | 2026 ICF, 4 units × 1,000 sqft, excellent, zone X, $600k · solar, passive house, hurricane straps, hip roof |
Controlling it: CLI & API
Every variable above is settable three ways: the Examples search form, the housing-simulate CLI, and the /label HTTP API (see Setup).
CLI
housing-simulate --address "123 Main St, Columbus, OH" \
--construction icf --year-built 2026 --condition excellent \
--foundation slab --sqft 1800 --value 350000 \
--solar --hurricane-straps --fire-sprinklers --json
Core flags: --preset, --address (or --lat/--lon), --construction, --year-built, --foundation, --condition, --flood-zone, --value, --units, --sqft, --lot-acres. Each resilience upgrade is a flag (e.g. --solar, --fortified-gold, --elevation-1ft). --json emits the full payload; --no-fetch runs offline.
Density comparison: add --density to compare the same parcel at 1–4 dwelling units (fixed lot, constant per-unit value). This is the density dividend. Set the counts with --density-units 1,2,4; combine with --json for machine-readable output.
API
GET /label?address=<addr>&preset=baseline&construction=icf&year_built=2026
&condition=excellent&sqft=1800&value=350000
&upgrades=solar,hurricane_straps,fire_sprinklers
Same parameters as the CLI; resilience upgrades are a single comma-separated upgrades= list. GET /suggest?q= powers the address autocomplete.
GET /density?address=<addr>&units=1,2,4&per_unit_value=250000
Compares the parcel across densities (fixed lot, vary units). Accepts every /label house parameter plus units= (comma-separated counts, default 1,2,3,4) and per_unit_value= (held constant; otherwise an explicit value= is the per-unit value, else the county median is auto-filled). Each scenario returns its scores plus fiscal productivity per acre (revenue_per_acre, cost_per_acre, net_fiscal_per_acre), and the response includes the headline density dividend (fiscal ratio, Infrastructure grade, and total-revenue-per-acre multiplier from fewest to most units). revenue_per_acre is property tax + user fees, matching the scope of cost_per_acre.
GET /timeline?address=<addr>&years=2000,2026,2040
Holds the address fixed and moves the clock. Accepts every /label house parameter plus years= (comma-separated as-of years for the building-ageing sweep; default a quarter-century back, now, and fifteen years on; at most six). Returns series (per dimension: ordered points, the delta, and a basis of observed, projection or aging — a measurement, a forecast, and arithmetic on a component-lifespan model are three different claims), point_in_time (a sentence for every dimension that carries no series, so a missing trend never renders as silence), and as_of (the Building headline grade at each year). Every point is scored on today’s breakpoints, so a change is a change in the place or the house rather than in how it ranks against a moving national average; a national_percentile is therefore surfaced only at the point its reference distribution was calibrated for.
Badge
GET /badge?address=<addr>&style=full&theme=auto
The label as a standalone SVG, for embedding on a page that isn’t ours. It renders inside a plain <img> — no script, no CORS, no build step on the host page:
<a href="https://housinglabel.dev/label.html">
<img src="https://your-api-host/badge?address=123%20Main%20St,%20Memphis,%20TN"
width="360" height="116"
alt="Housing Nutrition Label — the building and the site, graded">
</a>
Takes address= (or lat=/lon=), plus style= (full 360×116, compact 300×40), theme= (auto, light, dark — auto follows the reader’s own setting through a media query browsers honour even inside an <img>), preset=, and label_text= to override the caption.
It shows two grades, not one — the building and the site, the same split the label leads with. A single letter would travel further and would be the wrong number: the two axes disagreeing is the information, and a composite that hides a D behind an A is the summary a badge is most tempted to print. An axis that could not be scored reads not scored rather than being rounded down to an F.
Two consequences of the <img> constraint: browsers disable links inside an <img>-loaded SVG, so wrap the badge in an anchor for click-through (the wordmark is drawn into the image so attribution survives if you don’t); and no web fonts are available, so text falls back to the reader’s system stack and long addresses truncate rather than being fitted.
The badge carries the trademark, which is licensed separately from the code — see the trademark policy. Displaying it unmodified, with attribution, is referential use and needs no permission.
Print & save
GET /label.svg?address=<addr>&theme=light&download=1
The whole label as one US Letter page of vector — both headline grades, all thirteen dimensions, the running-cost line, and the disclaimer in full — for printing, filing, or dropping into a report. It takes every /label house parameter and is scored through the same path, so a saved sheet cannot disagree with the label it was saved from, refinements included. Beyond those: theme= (light by default, where the badge defaults to auto — this one is made for paper, and paper has no dark mode), download=1 for an attachment rather than an inline render, label_text= to caption it with an address you have already formatted, and scored= to stamp a date in the footer.
Three things it does differently from the card on this site, all of them because paper is not a screen. It has an edge: the layout is budgeted against the page, so a thirteen-dimension label lands on one sheet rather than breaking across two wherever the browser chose — the per-row detail panels are the one thing left off, because printing all thirteen would be a booklet, not a label. Colour is never the only channel: every grade is a letter and a bar length and a number, so a grayscale printer or a photocopy loses nothing. The text is still text: real <text> elements rather than outlines, so the sheet stays searchable, selectable, and editable in Illustrator or Inkscape.
Printing from the site needs no API call: the Print label button — in the search form's own action row, disabled until something has been scored — prints the page as it stands — the rows you expanded included, the controls dropped — and adds a colophon naming the source and the date, because a page of grades with no source and no date is the copy that gets misread a year later.
Keys & usage
No key is required, and on a self-hosted instance none exists. Every caller is anonymous unless the operator has issued keys, and an anonymous caller is unmetered — the same service that ran before keys did. Where keys have been issued, sending one as an X-API-Key header gets you a rate-limit bucket of your own rather than one shared with everybody behind the same address, plus your plan’s daily allowance. It does not change the numbers: a scored address returns the same label on every plan.
?key= also works and is not equivalent. A query string is part of the request line, so it is captured verbatim by the server’s access log, by any proxy in front of it, by browser history, and by the Referer sent to third parties — none of which the API can unwrite. Prefer the header wherever you can set one. ?key= exists for callers that genuinely cannot (an <img> or iframe embed, a quick curl); requests carrying it are answered no-store so the key-bearing URL stays out of the disk cache, and a key that has travelled that way is one worth rotating.
GET /usage
Reports the calling key’s plan, what it has spent today, what remains, and that the day resets at 00:00 UTC. It answers for the caller and only the caller — there is no parameter that points it at another key.
Anonymous callers are counted too, one row each: a badge is attributed to the site embedding it (the Referer’s host, so a thousand readers of one page count as one embedder), everything else to the calling address. That is attribution rather than authentication — a Referer is trivially forged, and it counts cooperative callers correctly without stopping an uncooperative one.
Metering counts scoring passes, not requests: /label, /label.svg and /badge are one each, /presets is five, a four-scenario /density is four, a three-point /timeline is three. Metered replies carry X-Quota-Limit, X-Quota-Remaining and X-Quota-Used; exhausting the day returns 429. A request rejected as invalid is never charged, and an unrecognised key is refused with 401 rather than quietly downgraded to the free tier.