US Building Permits - 19 sources, one schema avatar

US Building Permits - 19 sources, one schema

Pricing

from $2.00 / 1,000 record scrapeds

Go to Apify Store
US Building Permits - 19 sources, one schema

US Building Permits - 19 sources, one schema

Building permits from 19 actively-maintained US municipal open-data portals (~11.4M records) normalised into a single schema with one date format, one address field and one currency field.

Pricing

from $2.00 / 1,000 record scrapeds

Rating

0.0

(0)

Developer

Rishi Vinodkumar

Rishi Vinodkumar

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

12 hours ago

Last modified

Share

US Building Permits — 19 sources, one schema

Building permits from nineteen US municipal open-data portals, normalised into a single schema with one date format, one address field, and one currency field.

~11,150,026 permit records across 19 actively-maintained sources.

SourceStateRecordsLast verified
New York CityNY~3,989,6472026-07-28
Austin (all trades)TX~2,367,6942026-07-28
ChicagoIL~842,5922026-07-28
New York City (electrical)NY~580,8642026-07-30
Seattle (electrical)WA~498,0272026-07-28
New OrleansLA~460,4902026-07-29
Los AngelesCA~403,2432026-07-25
Montgomery CountyMD~319,3922026-07-28
AustinTX~285,8512026-07-06
Seattle (trade)WA~284,6882026-07-29
SeattleWA~191,830
Montgomery County (residential)MD~185,6962026-07-30
CincinnatiOH~178,460
Montgomery County (mechanical)MD~157,3882026-07-30
MesaAZ~155,5692026-07-27
Baton RougeLA~142,483
Marin CountyCA~50,2802026-07-29
Montgomery County (commercial)MD~41,6752026-07-30
CambridgeMA~14,1572026-07-28

Registered but excluded by default (abandoned upstream, kept so the staleness is documented rather than rediscovered):

  • Dallas, TX — last record 2020-08-29
  • Gainesville, FL — last record 2023-02-28

Why this exists

Every city below publishes permits on Socrata, so the transport is identical and trivial. Everything else differs. The issue-date column alone is spelled nine ways:

CityColumnType
Chicagoissue_datetimestamp
New York Cityissuance_datetext MM/DD/YYYY
Seattleissueddatetimestamp
Austinissue_datetimestamp
Los Angelesissue_datetimestamp
Cincinnatiissueddatetimestamp
Baton Rougeissueddatetimestamp
Mesaopened_datetimestamp (application date)
Cambridgeissue_datetimestamp

Addresses are worse — Chicago splits into number/direction/name, NYC into house/street/borough, Seattle keeps one preformatted line, Cambridge uses full_address. Project value appears as estprojectcost, valuation, total_job_valuation, projectvalue, building_cost, and icc_value.

Writing nineteen adapters is a week. Maintaining them as cities silently rename and retype columns is the actual cost, and it never ends.

* NYC's dataset holds 4M rows going back to 1989, but only ~4.6k permits were issued in 2026 and ~10k in 2025 — the bulk is historical.

Output schema

{
"source_city": "chicago",
"city_label": "Chicago",
"state": "IL",
"permit_number": "101084879",
"permit_type": "PERMIT - RENOVATION/ALTERATION",
"permit_subtype": "STANDARD PLAN REVIEW",
"status": "ACTIVE",
"description": "INTERIOR ALTERATION OF EXISTING CORRIDORS AND RESTROOMS...",
"issue_date": "2026-07-28",
"issue_date_is_approximate": false,
"application_date": "2026-06-25",
"expiration_date": null,
"address": "600 W CHICAGO AVE",
"city_name": "Chicago",
"zip_code": "60654",
"latitude": 41.8965851912,
"longitude": -87.6429961817,
"project_value_usd": 351750.0,
"fee_usd": 600.0,
"contractor_name": "MATTHEW RYAN",
"applicant_name": null,
"dwelling_units": null,
"source_url": "https://data.cityofchicago.org/resource/ydr8-5enu.json",
"source_dataset_id": "ydr8-5enu"
}

permit_number, issue_date, address, latitude and longitude are populated for 100% of records across all nine live cities.

Honest field-availability notes

Some fields are absent because the city does not publish them, not because normalisation failed. Rather than emit a plausible-looking null and let you discover this in your own funnel metrics:

  • No project valuation: NYC, Mesa
  • No contractor name: Seattle, Austin, Los Angeles
  • No site ZIP: Mesa, Cambridge (Mesa publishes contractor ZIP only)
  • issue_date_is_approximate: true on Mesa — it publishes an application date, not an issue date. Every record is flagged so you can exclude it.

Set includeRawRecord: true to attach the untouched municipal record under raw and check anything yourself.

Who this is for

  • Solar / roofing / HVAC contractors buying geocoded permit leads. LA additionally exposes a solar flag.
  • Construction-materials suppliers sizing demand by metro and value band.
  • Proptech and lead-gen platforms needing a permit feed without owning nine scrapers.
  • Market researchers tracking construction activity across metros.

Usage

Typical lead-generation run — high-value residential work in the last month:

{
"cities": ["chicago", "los_angeles", "seattle", "cincinnati"],
"issuedAfter": "2026-07-01",
"minProjectValue": 50000,
"requireAddress": true,
"maxResults": 5000
}

Solar-specific:

{ "cities": ["los_angeles", "austin", "mesa"], "search": "solar", "issuedAfter": "2026-01-01" }

Careful with minProjectValue: records where the city publishes no valuation are excluded, so setting it drops NYC and Mesa entirely. That is deliberate — a lead you cannot size did not meet your threshold.

Local development

No Apify runtime needed; the scraping logic is independent of the platform.

pip install requests
python local_run.py --coverage # registry + row counts
python local_run.py --cities chicago,seattle --issued-after 2026-06-01 --limit 20
python verify.py # health-check every source

verify.py is the maintenance early-warning system. Run it on a schedule — it catches the three ways these feeds break:

  1. Abandoned upstream (Dallas: metadata claims fresh, data ends 2020)
  2. Renamed column (mapping is alias-tolerant, but a rename matching no alias silently nulls a field)
  3. Retyped column (NYC's text dates make range filters return plausible-looking nonsense instead of an error)

It caught a real bug during development: a suffix column on Chicago that does not exist.

Public, logged-out municipal open-data endpoints served through each city's official Socrata API. No authentication, no account, no terms accepted, no anti-bot circumvention, no personal contact data. Contractor and applicant names are published by the municipality as part of the public record.

Rate limits are respected with exponential backoff — these are public-good servers. Supplying a free Socrata app token raises your limit above the shared anonymous pool.