US Building Permits - 19 sources, one schema
Pricing
from $2.00 / 1,000 record scrapeds
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
12 hours ago
Last modified
Categories
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.
| Source | State | Records | Last verified |
|---|---|---|---|
| New York City | NY | ~3,989,647 | 2026-07-28 |
| Austin (all trades) | TX | ~2,367,694 | 2026-07-28 |
| Chicago | IL | ~842,592 | 2026-07-28 |
| New York City (electrical) | NY | ~580,864 | 2026-07-30 |
| Seattle (electrical) | WA | ~498,027 | 2026-07-28 |
| New Orleans | LA | ~460,490 | 2026-07-29 |
| Los Angeles | CA | ~403,243 | 2026-07-25 |
| Montgomery County | MD | ~319,392 | 2026-07-28 |
| Austin | TX | ~285,851 | 2026-07-06 |
| Seattle (trade) | WA | ~284,688 | 2026-07-29 |
| Seattle | WA | ~191,830 | — |
| Montgomery County (residential) | MD | ~185,696 | 2026-07-30 |
| Cincinnati | OH | ~178,460 | — |
| Montgomery County (mechanical) | MD | ~157,388 | 2026-07-30 |
| Mesa | AZ | ~155,569 | 2026-07-27 |
| Baton Rouge | LA | ~142,483 | — |
| Marin County | CA | ~50,280 | 2026-07-29 |
| Montgomery County (commercial) | MD | ~41,675 | 2026-07-30 |
| Cambridge | MA | ~14,157 | 2026-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:
| City | Column | Type |
|---|---|---|
| Chicago | issue_date | timestamp |
| New York City | issuance_date | text MM/DD/YYYY |
| Seattle | issueddate | timestamp |
| Austin | issue_date | timestamp |
| Los Angeles | issue_date | timestamp |
| Cincinnati | issueddate | timestamp |
| Baton Rouge | issueddate | timestamp |
| Mesa | opened_date | timestamp (application date) |
| Cambridge | issue_date | timestamp |
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: trueon 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
solarflag. - 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 requestspython local_run.py --coverage # registry + row countspython local_run.py --cities chicago,seattle --issued-after 2026-06-01 --limit 20python 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:
- Abandoned upstream (Dallas: metadata claims fresh, data ends 2020)
- Renamed column (mapping is alias-tolerant, but a rename matching no alias silently nulls a field)
- 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.
Legal
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.