[object Object]

← back to Commercialrealestate

CRE: live Census ACS demographics for 73 LA submarkets (keyless Census Reporter) — renter%, med rent, income, pop, home value, rent burden on every card

b6964fda46607e7be8a6ef9c3062c3e2a76334e4 · 2026-06-27 00:42:30 -0700 · Steve

Files touched

Diff

commit b6964fda46607e7be8a6ef9c3062c3e2a76334e4
Author: Steve <steve@designerwallcoverings.com>
Date:   Sat Jun 27 00:42:30 2026 -0700

    CRE: live Census ACS demographics for 73 LA submarkets (keyless Census Reporter) — renter%, med rent, income, pop, home value, rent burden on every card
---
 data/demographics.json        | 810 ++++++++++++++++++++++++++++++++++++++++++
 scripts/fetch-demographics.js |  81 ++---
 2 files changed, 849 insertions(+), 42 deletions(-)

diff --git a/data/demographics.json b/data/demographics.json
new file mode 100644
index 0000000..54f40f9
--- /dev/null
+++ b/data/demographics.json
@@ -0,0 +1,810 @@
+{
+  "generated": "2026-06-27",
+  "source": "US Census ACS 5-year, per representative ZCTA (Census Reporter)",
+  "count": 73,
+  "byCity": {
+    "los angeles": {
+      "zcta": "90015",
+      "population": 24704,
+      "median_income": 69268,
+      "median_gross_rent": 2426,
+      "renter_pct": 88.6,
+      "median_age": 32.9,
+      "median_home_value": 786000,
+      "rent_burden_pct": 32.5,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "pasadena": {
+      "zcta": "91101",
+      "population": 21165,
+      "median_income": 87813,
+      "median_gross_rent": 2270,
+      "renter_pct": 84.8,
+      "median_age": 36.5,
+      "median_home_value": 682300,
+      "rent_burden_pct": 30.7,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "inglewood": {
+      "zcta": "90301",
+      "population": 36060,
+      "median_income": 65806,
+      "median_gross_rent": 1732,
+      "renter_pct": 72,
+      "median_age": 39.3,
+      "median_home_value": 755900,
+      "rent_burden_pct": 34.6,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "long beach": {
+      "zcta": "90802",
+      "population": 40434,
+      "median_income": 74510,
+      "median_gross_rent": 1968,
+      "renter_pct": 79,
+      "median_age": 35.3,
+      "median_home_value": 542600,
+      "rent_burden_pct": 34.4,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "san pedro": {
+      "zcta": "90731",
+      "population": 61944,
+      "median_income": 76395,
+      "median_gross_rent": 1740,
+      "renter_pct": 67.4,
+      "median_age": 38.6,
+      "median_home_value": 851000,
+      "rent_burden_pct": 34.5,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "santa monica": {
+      "zcta": "90404",
+      "population": 22978,
+      "median_income": 95139,
+      "median_gross_rent": 2239,
+      "renter_pct": 78.6,
+      "median_age": 40.5,
+      "median_home_value": 1244400,
+      "rent_burden_pct": 28.2,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "torrance": {
+      "zcta": "90503",
+      "population": 43454,
+      "median_income": 125912,
+      "median_gross_rent": 2302,
+      "renter_pct": 47.4,
+      "median_age": 41.3,
+      "median_home_value": 1099700,
+      "rent_burden_pct": 29.5,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "glendale": {
+      "zcta": "91205",
+      "population": 34254,
+      "median_income": 64564,
+      "median_gross_rent": 1938,
+      "renter_pct": 82.3,
+      "median_age": 41,
+      "median_home_value": 800800,
+      "rent_burden_pct": 39.1,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "north hollywood": {
+      "zcta": "91601",
+      "population": 36992,
+      "median_income": 79607,
+      "median_gross_rent": 2158,
+      "renter_pct": 83.3,
+      "median_age": 34.2,
+      "median_home_value": 1000000,
+      "rent_burden_pct": 35.3,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "pomona": {
+      "zcta": "91766",
+      "population": 69327,
+      "median_income": 81991,
+      "median_gross_rent": 1842,
+      "renter_pct": 45.6,
+      "median_age": 35.4,
+      "median_home_value": 599000,
+      "rent_burden_pct": 35.4,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "van nuys": {
+      "zcta": "91405",
+      "population": 56033,
+      "median_income": 62900,
+      "median_gross_rent": 1780,
+      "renter_pct": 72.7,
+      "median_age": 36.3,
+      "median_home_value": 737700,
+      "rent_burden_pct": 41,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "burbank": {
+      "zcta": "91505",
+      "population": 31744,
+      "median_income": 109953,
+      "median_gross_rent": 2397,
+      "renter_pct": 56.3,
+      "median_age": 38.7,
+      "median_home_value": 1061200,
+      "rent_burden_pct": 30.6,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "el monte": {
+      "zcta": "91731",
+      "population": 27620,
+      "median_income": 62215,
+      "median_gross_rent": 1669,
+      "renter_pct": 60.4,
+      "median_age": 36.6,
+      "median_home_value": 635600,
+      "rent_burden_pct": 35.8,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "culver city": {
+      "zcta": "90232",
+      "population": 16554,
+      "median_income": 122396,
+      "median_gross_rent": 2678,
+      "renter_pct": 61.5,
+      "median_age": 37.3,
+      "median_home_value": 1570600,
+      "rent_burden_pct": 28.9,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "west hollywood": {
+      "zcta": "90046",
+      "population": 48296,
+      "median_income": 96250,
+      "median_gross_rent": 2194,
+      "renter_pct": 77.8,
+      "median_age": 40.2,
+      "median_home_value": 1515000,
+      "rent_burden_pct": 29.9,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "northridge": {
+      "zcta": "91324",
+      "population": 30699,
+      "median_income": 99610,
+      "median_gross_rent": 2307,
+      "renter_pct": 53.3,
+      "median_age": 37.7,
+      "median_home_value": 906300,
+      "rent_burden_pct": 39.1,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "whittier": {
+      "zcta": "90602",
+      "population": 25905,
+      "median_income": 68505,
+      "median_gross_rent": 1787,
+      "renter_pct": 61.1,
+      "median_age": 34.3,
+      "median_home_value": 766300,
+      "rent_burden_pct": 36.3,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "downey": {
+      "zcta": "90241",
+      "population": 45319,
+      "median_income": 88006,
+      "median_gross_rent": 1956,
+      "renter_pct": 58.3,
+      "median_age": 36.7,
+      "median_home_value": 829000,
+      "rent_burden_pct": 32.1,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "reseda": {
+      "zcta": "91335",
+      "population": 74526,
+      "median_income": 80143,
+      "median_gross_rent": 1874,
+      "renter_pct": 49.8,
+      "median_age": 39.2,
+      "median_home_value": 751700,
+      "rent_burden_pct": 39.6,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "venice": {
+      "zcta": "90291",
+      "population": 26324,
+      "median_income": 122738,
+      "median_gross_rent": 2703,
+      "renter_pct": 67.1,
+      "median_age": 40,
+      "median_home_value": 2000001,
+      "rent_burden_pct": 30.7,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "canoga park": {
+      "zcta": "91303",
+      "population": 29805,
+      "median_income": 74474,
+      "median_gross_rent": 2057,
+      "renter_pct": 78.4,
+      "median_age": 33.5,
+      "median_home_value": 683000,
+      "rent_burden_pct": 35.3,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "beverly hills": {
+      "zcta": "90210",
+      "population": 19004,
+      "median_income": 187801,
+      "median_gross_rent": 3251,
+      "renter_pct": 29.3,
+      "median_age": 51.9,
+      "median_home_value": 2000001,
+      "rent_burden_pct": 41.3,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "sherman oaks": {
+      "zcta": "91403",
+      "population": 25793,
+      "median_income": 116170,
+      "median_gross_rent": 2417,
+      "renter_pct": 55.3,
+      "median_age": 41,
+      "median_home_value": 1520000,
+      "rent_burden_pct": 31.9,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "panorama city": {
+      "zcta": "91402",
+      "population": 65754,
+      "median_income": 57369,
+      "median_gross_rent": 1674,
+      "renter_pct": 66.4,
+      "median_age": 35.1,
+      "median_home_value": 624300,
+      "rent_burden_pct": 42.4,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "tujunga": {
+      "zcta": "91042",
+      "population": 26928,
+      "median_income": 85603,
+      "median_gross_rent": 1874,
+      "renter_pct": 47.1,
+      "median_age": 45.8,
+      "median_home_value": 840800,
+      "rent_burden_pct": 41.1,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "sun valley": {
+      "zcta": "91352",
+      "population": 46899,
+      "median_income": 78239,
+      "median_gross_rent": 1830,
+      "renter_pct": 49.8,
+      "median_age": 37.3,
+      "median_home_value": 764800,
+      "rent_burden_pct": 36.7,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "altadena": {
+      "zcta": "91001",
+      "population": 35475,
+      "median_income": 134903,
+      "median_gross_rent": 2437,
+      "renter_pct": 20.1,
+      "median_age": 46.3,
+      "median_home_value": 1135200,
+      "rent_burden_pct": 40,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "montebello": {
+      "zcta": "90640",
+      "population": 61382,
+      "median_income": 79625,
+      "median_gross_rent": 1827,
+      "renter_pct": 53.8,
+      "median_age": 40.1,
+      "median_home_value": 699700,
+      "rent_burden_pct": 35.2,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "lake balboa": {
+      "zcta": "91406",
+      "population": 51953,
+      "median_income": 78429,
+      "median_gross_rent": 1906,
+      "renter_pct": 59.4,
+      "median_age": 37.5,
+      "median_home_value": 808900,
+      "rent_burden_pct": 37.2,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "granada hills": {
+      "zcta": "91344",
+      "population": 52890,
+      "median_income": 119345,
+      "median_gross_rent": 2337,
+      "renter_pct": 26.6,
+      "median_age": 43.9,
+      "median_home_value": 904300,
+      "rent_burden_pct": 36.5,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "woodland hills": {
+      "zcta": "91367",
+      "population": 45889,
+      "median_income": 108653,
+      "median_gross_rent": 2743,
+      "renter_pct": 54.6,
+      "median_age": 39.7,
+      "median_home_value": 1067000,
+      "rent_burden_pct": 34,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "san gabriel": {
+      "zcta": "91776",
+      "population": 36952,
+      "median_income": 82155,
+      "median_gross_rent": 1860,
+      "renter_pct": 57.2,
+      "median_age": 43.1,
+      "median_home_value": 859600,
+      "rent_burden_pct": 30.5,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "temple city": {
+      "zcta": "91780",
+      "population": 35588,
+      "median_income": 103659,
+      "median_gross_rent": 2155,
+      "renter_pct": 38.1,
+      "median_age": 42.9,
+      "median_home_value": 950300,
+      "rent_burden_pct": 33.6,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "north hills": {
+      "zcta": "91343",
+      "population": 60783,
+      "median_income": 81430,
+      "median_gross_rent": 1867,
+      "renter_pct": 51.8,
+      "median_age": 36.7,
+      "median_home_value": 823700,
+      "rent_burden_pct": 39.7,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "studio city": {
+      "zcta": "91604",
+      "population": 32469,
+      "median_income": 141875,
+      "median_gross_rent": 2535,
+      "renter_pct": 54.9,
+      "median_age": 40.7,
+      "median_home_value": 1700300,
+      "rent_burden_pct": 29.7,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "sunland": {
+      "zcta": "91040",
+      "population": 20821,
+      "median_income": 98256,
+      "median_gross_rent": 1830,
+      "renter_pct": 33.5,
+      "median_age": 44.6,
+      "median_home_value": 861600,
+      "rent_burden_pct": 36.1,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "pico rivera": {
+      "zcta": "90660",
+      "population": 60272,
+      "median_income": 88201,
+      "median_gross_rent": 1786,
+      "renter_pct": 29.5,
+      "median_age": 40.4,
+      "median_home_value": 648600,
+      "rent_burden_pct": 35.4,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "rosemead": {
+      "zcta": "91770",
+      "population": 58382,
+      "median_income": 75000,
+      "median_gross_rent": 1847,
+      "renter_pct": 51,
+      "median_age": 44.5,
+      "median_home_value": 790200,
+      "rent_burden_pct": 34.9,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "lancaster": {
+      "zcta": "93534",
+      "population": 41430,
+      "median_income": 61866,
+      "median_gross_rent": 1627,
+      "renter_pct": 62.7,
+      "median_age": 35.6,
+      "median_home_value": 375200,
+      "rent_burden_pct": 36.9,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "newhall": {
+      "zcta": "91321",
+      "population": 31989,
+      "median_income": 91092,
+      "median_gross_rent": 2134,
+      "renter_pct": 39.2,
+      "median_age": 36.5,
+      "median_home_value": 691600,
+      "rent_burden_pct": 38.9,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "pacoima": {
+      "zcta": "91331",
+      "population": 97608,
+      "median_income": 84227,
+      "median_gross_rent": 1844,
+      "renter_pct": 37.6,
+      "median_age": 35.4,
+      "median_home_value": 633200,
+      "rent_burden_pct": 37.2,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "valley village": {
+      "zcta": "91607",
+      "population": 31890,
+      "median_income": 87874,
+      "median_gross_rent": 2065,
+      "renter_pct": 70.1,
+      "median_age": 38.5,
+      "median_home_value": 1030500,
+      "rent_burden_pct": 35.1,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "sylmar": {
+      "zcta": "91342",
+      "population": 93301,
+      "median_income": 98118,
+      "median_gross_rent": 1963,
+      "renter_pct": 32.2,
+      "median_age": 37.5,
+      "median_home_value": 695600,
+      "rent_burden_pct": 39.8,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "winnetka": {
+      "zcta": "91306",
+      "population": 47176,
+      "median_income": 93151,
+      "median_gross_rent": 1925,
+      "renter_pct": 43.7,
+      "median_age": 39,
+      "median_home_value": 800000,
+      "rent_burden_pct": 38.9,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "la crescenta": {
+      "zcta": "91214",
+      "population": 30817,
+      "median_income": 140121,
+      "median_gross_rent": 2455,
+      "renter_pct": 25.2,
+      "median_age": 41.7,
+      "median_home_value": 1135200,
+      "rent_burden_pct": 29.8,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "baldwin park": {
+      "zcta": "91706",
+      "population": 71082,
+      "median_income": 81122,
+      "median_gross_rent": 1866,
+      "renter_pct": 42,
+      "median_age": 38.2,
+      "median_home_value": 609000,
+      "rent_burden_pct": 33.3,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "porter ranch": {
+      "zcta": "91326",
+      "population": 38428,
+      "median_income": 148281,
+      "median_gross_rent": 3145,
+      "renter_pct": 24.2,
+      "median_age": 43.6,
+      "median_home_value": 1106000,
+      "rent_burden_pct": 43.1,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "hollywood": {
+      "zcta": "90028",
+      "population": 32883,
+      "median_income": 61349,
+      "median_gross_rent": 1899,
+      "renter_pct": 96.6,
+      "median_age": 35.6,
+      "median_home_value": 1043100,
+      "rent_burden_pct": 35.2,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "marina del rey": {
+      "zcta": "90292",
+      "population": 23982,
+      "median_income": 146167,
+      "median_gross_rent": 3501,
+      "renter_pct": 71.1,
+      "median_age": 38.7,
+      "median_home_value": 1272200,
+      "rent_burden_pct": 29.7,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "malibu": {
+      "zcta": "90265",
+      "population": 15918,
+      "median_income": 196742,
+      "median_gross_rent": 3501,
+      "renter_pct": 21.5,
+      "median_age": 52,
+      "median_home_value": 2000001,
+      "rent_burden_pct": 28.4,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "redondo beach": {
+      "zcta": "90277",
+      "population": 34844,
+      "median_income": 127795,
+      "median_gross_rent": 2742,
+      "renter_pct": 51.5,
+      "median_age": 45.9,
+      "median_home_value": 1476000,
+      "rent_burden_pct": 31.2,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "signal hill": {
+      "zcta": "90755",
+      "population": 11521,
+      "median_income": 113512,
+      "median_gross_rent": 1851,
+      "renter_pct": 49.5,
+      "median_age": 41.9,
+      "median_home_value": 787300,
+      "rent_burden_pct": 25.1,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "hacienda heights": {
+      "zcta": "91745",
+      "population": 54351,
+      "median_income": 109183,
+      "median_gross_rent": 2299,
+      "renter_pct": 24.5,
+      "median_age": 44.4,
+      "median_home_value": 820800,
+      "rent_burden_pct": 30.8,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "arcadia": {
+      "zcta": "91006",
+      "population": 31582,
+      "median_income": 123533,
+      "median_gross_rent": 2223,
+      "renter_pct": 31.3,
+      "median_age": 44,
+      "median_home_value": 1260000,
+      "rent_burden_pct": 33.2,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "palmdale": {
+      "zcta": "93550",
+      "population": 80645,
+      "median_income": 62078,
+      "median_gross_rent": 1668,
+      "renter_pct": 48.8,
+      "median_age": 30.7,
+      "median_home_value": 420600,
+      "rent_burden_pct": 40.7,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "santa clarita": {
+      "zcta": "91350",
+      "population": 43973,
+      "median_income": 140110,
+      "median_gross_rent": 2531,
+      "renter_pct": 17.5,
+      "median_age": 38.2,
+      "median_home_value": 801300,
+      "rent_burden_pct": 42.5,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "mission hills": {
+      "zcta": "91345",
+      "population": 18714,
+      "median_income": 94215,
+      "median_gross_rent": 2021,
+      "renter_pct": 30.6,
+      "median_age": 40.8,
+      "median_home_value": 712200,
+      "rent_burden_pct": 41.3,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "tarzana": {
+      "zcta": "91356",
+      "population": 30942,
+      "median_income": 107378,
+      "median_gross_rent": 2009,
+      "renter_pct": 42,
+      "median_age": 42.3,
+      "median_home_value": 1229000,
+      "rent_burden_pct": 36.1,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "gardena": {
+      "zcta": "90247",
+      "population": 47053,
+      "median_income": 77333,
+      "median_gross_rent": 1805,
+      "renter_pct": 58.7,
+      "median_age": 37.7,
+      "median_home_value": 659100,
+      "rent_burden_pct": 32.7,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "agoura hills": {
+      "zcta": "91301",
+      "population": 23879,
+      "median_income": 163317,
+      "median_gross_rent": 3184,
+      "renter_pct": 17.6,
+      "median_age": 46.7,
+      "median_home_value": 1116200,
+      "rent_burden_pct": 39.2,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "alhambra": {
+      "zcta": "91801",
+      "population": 53381,
+      "median_income": 89156,
+      "median_gross_rent": 1981,
+      "renter_pct": 62.6,
+      "median_age": 41.5,
+      "median_home_value": 834000,
+      "rent_burden_pct": 30.8,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "west hills": {
+      "zcta": "91307",
+      "population": 26580,
+      "median_income": 151190,
+      "median_gross_rent": 3501,
+      "renter_pct": 20.5,
+      "median_age": 44.2,
+      "median_home_value": 963900,
+      "rent_burden_pct": 33.6,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "san fernando": {
+      "zcta": "91340",
+      "population": 33424,
+      "median_income": 85261,
+      "median_gross_rent": 1813,
+      "renter_pct": 35.5,
+      "median_age": 37.4,
+      "median_home_value": 661500,
+      "rent_burden_pct": 38,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "eagle rock": {
+      "zcta": "90041",
+      "population": 27920,
+      "median_income": 114526,
+      "median_gross_rent": 1808,
+      "renter_pct": 45.4,
+      "median_age": 41,
+      "median_home_value": 1192200,
+      "rent_burden_pct": 30,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "mar vista": {
+      "zcta": "90066",
+      "population": 56740,
+      "median_income": 114141,
+      "median_gross_rent": 2279,
+      "renter_pct": 61.7,
+      "median_age": 38.2,
+      "median_home_value": 1695400,
+      "rent_burden_pct": 27.7,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "pacific palisades": {
+      "zcta": "90272",
+      "population": 21390,
+      "median_income": 189713,
+      "median_gross_rent": 3501,
+      "renter_pct": 20.1,
+      "median_age": 48.3,
+      "median_home_value": 2000001,
+      "rent_burden_pct": 38.5,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "santa fe springs": {
+      "zcta": "90670",
+      "population": 17851,
+      "median_income": 88872,
+      "median_gross_rent": 1994,
+      "renter_pct": 37.2,
+      "median_age": 39.3,
+      "median_home_value": 659600,
+      "rent_burden_pct": 32,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "south el monte": {
+      "zcta": "91733",
+      "population": 41255,
+      "median_income": 68278,
+      "median_gross_rent": 1681,
+      "renter_pct": 58.3,
+      "median_age": 38.2,
+      "median_home_value": 621800,
+      "rent_burden_pct": 36.6,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "norwalk": {
+      "zcta": "90650",
+      "population": 99900,
+      "median_income": 100085,
+      "median_gross_rent": 2090,
+      "renter_pct": 31.7,
+      "median_age": 37.3,
+      "median_home_value": 644700,
+      "rent_burden_pct": 34.9,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "monrovia": {
+      "zcta": "91016",
+      "population": 41140,
+      "median_income": 96540,
+      "median_gross_rent": 2106,
+      "renter_pct": 52.1,
+      "median_age": 38.4,
+      "median_home_value": 896700,
+      "rent_burden_pct": 31.7,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "littlerock": {
+      "zcta": "93543",
+      "population": 12275,
+      "median_income": 72488,
+      "median_gross_rent": 1759,
+      "renter_pct": 26,
+      "median_age": 37.7,
+      "median_home_value": 388400,
+      "rent_burden_pct": 45,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "castaic": {
+      "zcta": "91384",
+      "population": 26478,
+      "median_income": 131689,
+      "median_gross_rent": 1745,
+      "renter_pct": 15.9,
+      "median_age": 35.8,
+      "median_home_value": 767300,
+      "rent_burden_pct": 44.1,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    },
+    "la canada flintridge": {
+      "zcta": "91011",
+      "population": 19935,
+      "median_income": 241875,
+      "median_gross_rent": 2873,
+      "renter_pct": 13.1,
+      "median_age": 44.6,
+      "median_home_value": 2000001,
+      "rent_burden_pct": 29.1,
+      "source": "US Census ACS 5-year (via Census Reporter)"
+    }
+  }
+}
\ No newline at end of file
diff --git a/scripts/fetch-demographics.js b/scripts/fetch-demographics.js
index bacd859..bf70e75 100644
--- a/scripts/fetch-demographics.js
+++ b/scripts/fetch-demographics.js
@@ -1,10 +1,11 @@
-// fetch-demographics.js — pull real US Census ACS 5-year (2022) demographics per LA County submarket
-// and write data/demographics.json, keyed by lowercased city name. Surfaces the figures that matter
-// for CRE underwriting: population, median household income, median gross rent, renter-occupied %,
-// median age, median home value, and rent burden (gross rent as % of income).
+// fetch-demographics.js — pull real US Census ACS 5-year demographics per LA County submarket and
+// write data/demographics.json, keyed by lowercased city name. Surfaces the figures that matter for
+// CRE underwriting: population, median household income, median gross rent, renter-occupied %, median
+// age, median home value, and rent burden (gross rent as % of income).
 //
-// Auth: needs a free Census API key in CENSUS_API_KEY (env or commercialrealestate/.env). Get one at
-// api.census.gov/data/key_signup.html. $0 — Census is free. Run: node scripts/fetch-demographics.js
+// SOURCE: Census Reporter (api.censusreporter.org) — a free, KEYLESS wrapper over the same Census ACS
+// 5-year data. $0, no signup. (The raw Census API at api.census.gov needs a key; this avoids that.)
+// Run: node scripts/fetch-demographics.js
 //
 // Each city maps to a representative ZCTA (ZIP-code tabulation area), the geography ACS publishes
 // uniformly across incorporated cities and LA neighborhoods alike. Figures are directional submarket
@@ -16,10 +17,6 @@ const path = require('path');
 const https = require('https');
 
 const ROOT = path.join(__dirname, '..');
-// Read CENSUS_API_KEY from env or .env
-let KEY = process.env.CENSUS_API_KEY;
-if (!KEY) { try { KEY = (fs.readFileSync(path.join(ROOT, '.env'), 'utf8').match(/^CENSUS_API_KEY=(.+)$/m) || [])[1]?.trim(); } catch (_) {} }
-if (!KEY) { console.error('No CENSUS_API_KEY (env or .env). Get a free one at api.census.gov/data/key_signup.html'); process.exit(2); }
 
 // Representative ZCTA per submarket (lowercased city name -> ZIP).
 const CITY_ZCTA = {
@@ -44,49 +41,49 @@ const CITY_ZCTA = {
   'la canada flintridge': '91011'
 };
 
-// ACS5 2022 variables we pull.
-const VARS = {
-  B01003_001E: 'population', B19013_001E: 'median_income', B25064_001E: 'median_gross_rent',
-  B25003_001E: '_occupied', B25003_003E: '_renter_occ', B01002_001E: 'median_age',
-  B25077_001E: 'median_home_value', B25071_001E: 'rent_burden_pct'
-};
-const VARLIST = Object.keys(VARS).join(',');
+// ACS tables we pull from Census Reporter.
+const TABLES = 'B01003,B19013,B25064,B25003,B01002,B25077,B25071';
 
 function get(url) {
   return new Promise((resolve, reject) => {
-    https.get(url, res => { let d = ''; res.on('data', c => d += c); res.on('end', () => resolve({ status: res.statusCode, body: d })); }).on('error', reject);
+    https.get(url, { headers: { 'User-Agent': 'cre-demographics/1.0' } },
+      res => { let d = ''; res.on('data', c => d += c); res.on('end', () => resolve({ status: res.statusCode, body: d })); }).on('error', reject);
   });
 }
-const numOrNull = v => { const n = +v; return Number.isFinite(n) && n > -666666 ? n : null; }; // ACS uses -666666666 for n/a
+const n = v => { const x = +v; return Number.isFinite(x) ? x : null; };
+const chunk = (arr, k) => { const o = []; for (let i = 0; i < arr.length; i += k) o.push(arr.slice(i, i + k)); return o; };
 
 (async () => {
-  const out = {};
   const cities = Object.entries(CITY_ZCTA);
-  console.log(`Fetching ACS 2022 demographics for ${cities.length} LA County submarkets…`);
+  const zToCity = {}; cities.forEach(([c, z]) => zToCity['86000US' + z] = { city: c, zcta: z });
+  console.log(`Fetching ACS demographics for ${cities.length} LA County submarkets via Census Reporter (keyless)…`);
+  const out = {};
   let ok = 0, fail = 0;
-  for (const [city, zcta] of cities) {
-    const url = `https://api.census.gov/data/2022/acs/acs5?get=NAME,${VARLIST}&for=zip%20code%20tabulation%20area:${zcta}&key=${KEY}`;
+  for (const group of chunk(Object.keys(zToCity), 18)) {
+    const url = `https://api.censusreporter.org/1.0/data/show/latest?table_ids=${TABLES}&geo_ids=${group.join(',')}`;
     try {
       const r = await get(url);
-      if (r.status !== 200) { console.log(`  ✗ ${city} (${zcta}) HTTP ${r.status}`); fail++; continue; }
-      const j = JSON.parse(r.body);            // [[header...],[row...]]
-      const header = j[0], row = j[1];
-      if (!row) { console.log(`  ✗ ${city} (${zcta}) no data`); fail++; continue; }
-      const rec = {};
-      header.forEach((h, i) => { if (VARS[h]) rec[VARS[h]] = numOrNull(row[i]); });
-      const renterPct = (rec._occupied && rec._renter_occ != null) ? Math.round(1000 * rec._renter_occ / rec._occupied) / 10 : null;
-      out[city] = {
-        zcta, population: rec.population, median_income: rec.median_income,
-        median_gross_rent: rec.median_gross_rent, renter_pct: renterPct,
-        median_age: rec.median_age, median_home_value: rec.median_home_value,
-        rent_burden_pct: rec.rent_burden_pct,
-        source: 'US Census ACS 5-year 2022', year: 2022
-      };
-      ok++;
-    } catch (e) { console.log(`  ✗ ${city} (${zcta}) ${e.message}`); fail++; }
+      if (r.status !== 200) { console.log(`  ✗ chunk HTTP ${r.status}`); fail += group.length; continue; }
+      const j = JSON.parse(r.body);
+      for (const geo of group) {
+        const d = j.data && j.data[geo]; const meta = zToCity[geo];
+        if (!d) { fail++; continue; }
+        const est = t => (d[t] && d[t].estimate) || {};
+        const pop = n(est('B01003').B01003001), inc = n(est('B19013').B19013001), rent = n(est('B25064').B25064001);
+        const occ = n(est('B25003').B25003001), ren = n(est('B25003').B25003003), age = n(est('B01002').B01002001);
+        const homeVal = n(est('B25077').B25077001), burden = n(est('B25071').B25071001);
+        out[meta.city] = {
+          zcta: meta.zcta, population: pop, median_income: inc, median_gross_rent: rent,
+          renter_pct: (occ && ren != null) ? Math.round(1000 * ren / occ) / 10 : null,
+          median_age: age, median_home_value: homeVal, rent_burden_pct: burden,
+          source: 'US Census ACS 5-year (via Census Reporter)'
+        };
+        ok++;
+      }
+    } catch (e) { console.log(`  ✗ chunk ${e.message}`); fail += group.length; }
   }
-  const payload = { generated: new Date().toISOString().slice(0, 10), source: 'US Census ACS 5-year (2022), per representative ZCTA', count: ok, byCity: out };
+  const payload = { generated: new Date().toISOString().slice(0, 10), source: 'US Census ACS 5-year, per representative ZCTA (Census Reporter)', count: ok, byCity: out };
   fs.writeFileSync(path.join(ROOT, 'data', 'demographics.json'), JSON.stringify(payload, null, 2));
-  console.log(`\n=== demographics.json written: ${ok} submarkets (${fail} failed) ===`);
-  if (ok) { const s = out[Object.keys(out)[0]]; console.log('sample:', JSON.stringify(s)); }
+  console.log(`\n=== demographics.json written: ${ok} submarkets (${fail} missing) ===`);
+  if (ok) { const k = Object.keys(out)[0]; console.log('sample', k, '→', JSON.stringify(out[k])); }
 })();

← baf6f58 CRE: add Census ACS demographics fetcher (70 LA submarkets)  ·  back to Commercialrealestate  ·  CRE: qwen narratives backfilled for all 1028 properties (the 6594d54 →