US Building Permits Scraper - Construction Leads
Pricing
from $1.50 / 1,000 permit records
US Building Permits Scraper - Construction Leads
Construction permits from 12 US cities (Chicago, NYC, LA, San Francisco, Seattle, Austin and more) in one unified format. Find new projects and contractor leads: filter by date, keyword, valuation and permit type. Official open data, no login, no personal data.
Pricing
from $1.50 / 1,000 permit records
Rating
0.0
(0)
Developer
Adam Abdou-Gustavson
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
US Building Permits Scraper — Construction Leads from 12 Cities, One Clean Format
Pull fresh building permits from 12 US cities and counties in a single run and get them back in one unified schema: permit number, issue date, permit type, work description, project valuation, address, ZIP, status, coordinates and (where the city publishes it) the contractor's business name.
All data comes from official city open-data portals (Socrata SODA APIs). No login, no proxies, no browser — so runs are fast, cheap and reliable.
Why use this building permit scraper?
- 🏗️ Construction & home-services lead generation — find new roofing, solar, pool, HVAC, ADU, remodel and demolition projects the week they are permitted.
- 📈 Market research — track construction activity and project value by city, ZIP or permit type.
- 🏘️ Real estate & investors — spot neighborhoods with rising renovation and new-construction activity.
- 🧱 Suppliers & distributors — target contractors that just pulled permits.
- 🤖 AI agents & automations — a clean, consistent JSON feed you can schedule daily and push to Sheets, CRMs, Slack or n8n/Make/Zapier.
Construction leads and contractor leads
Use the permit feed as a construction leads list. New roofing, solar, pool, HVAC, ADU, remodel and demolition construction permits show up here soon after the city issues them, usually within days. Where a city publishes the contractor's company name (New York City, Seattle, Austin and Cincinnati), each record includes it in contractorBusiness, so suppliers and subcontractors also get contractor leads: companies that just pulled a permit. The other cities publish no contractor field, so those records give you the project and address but no contractor. No personal names, phone numbers or emails are ever output.
Supported cities
| City | Source |
|---|---|
| Chicago, IL | data.cityofchicago.org |
| New York City, NY (DOB NOW: Build approved permits) | data.cityofnewyork.us |
| Los Angeles, CA (LADBS, 2020–present) | data.lacity.org |
| San Francisco, CA | data.sf.gov |
| Seattle, WA | data.seattle.gov |
| Austin, TX | data.austintexas.gov |
| New Orleans, LA | data.nola.gov |
| Cambridge, MA (new construction) | data.cambridgema.gov |
| Montgomery County, MD (residential) | data.montgomerycountymd.gov |
| Mesa, AZ | data.mesaaz.gov |
| Cincinnati, OH | data.cincinnati-oh.gov |
| Baton Rouge, LA (East Baton Rouge Parish) | data.brla.gov |
Need another city? Open an issue on the Actor page and we will look at adding it.
Input
| Field | What it does |
|---|---|
cities | Cities to include. Empty = all. |
issuedAfter / daysBack | Date window (default: last 30 days). |
keywords | Keep permits whose type/description mentions any keyword, e.g. solar, roof, pool, ADU. |
minValuation | Minimum reported project value in USD. |
maxResultsPerCity | Cap per city, newest first. |
includeRaw | Also return the original record (personal fields removed). |
Example — solar and roofing jobs over $10k in the last 90 days:
{"cities": ["austin", "seattle", "los-angeles", "san-francisco"],"daysBack": 90,"keywords": ["solar", "roof"],"minValuation": 10000,"maxResultsPerCity": 500}
Output
{"city": "Austin, TX","cityKey": "austin","state": "TX","permitNumber": "2026-128634 PP","issuedDate": "2026-10-05","permitType": "Plumbing Permit","workClass": "Irrigation","description": "Install Sprinkler System","valuationUsd": 4500,"address": "9309 BREEZE HILL DR","zip": "78748","status": "Active","latitude": 30.17,"longitude": -97.82,"contractorBusiness": "Example Irrigation LLC","sourceUrl": "https://abc.austintexas.gov/...","sourceDataset": "https://data.austintexas.gov/resource/3syk-w9eu","scrapedAt": "2026-10-17T20:00:00+00:00"}
Download as JSON, CSV, Excel or via the Apify API. A SUMMARY record in the key-value store shows counts per city.
Pricing
Pay only for results: $1.50 per 1,000 permits (pay-per-event, charged per permit saved). No monthly rental.
What will it cost?
| Permits | Cost |
|---|---|
| 150 permits (the pre-filled form: 3 cities × 50) | $0.23 |
| 1,000 permits | $1.50 |
| 10,000 permits | $15.00 |
| 100,000 permits | $150.00 |
Use maxResultsPerCity and the number of cities to control how many permits you get. Each run also has a $0.00005 start fee (one per GB of memory; the default memory needs one), which is too small to change these numbers. You pay only for these events: no rental fee and no separate compute charge. Set a maximum cost per run in the run options (or maxTotalChargeUsd in the API) and the Actor stops cleanly when it reaches it.
Use it via API, code or AI agents
Everything in the Console also works over the API, so you can run it from code, a scheduler or an AI agent. Replace <YOUR_APIFY_TOKEN> with your token from Apify Console → Settings → API & Integrations.
REST: run and get the results in one call (waits up to 5 minutes; maxTotalChargeUsd caps what the run can cost):
curl -X POST "https://api.apify.com/v2/acts/batreek~us-building-permits/run-sync-get-dataset-items?maxTotalChargeUsd=1" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"cities": ["austin", "seattle"], "daysBack": 7, "keywords": ["solar", "roof"], "maxResultsPerCity": 50}'
Python (pip install apify-client):
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("batreek/us-building-permits").call(run_input={"cities": ["austin","seattle"],"daysBack": 7,"keywords": ["solar","roof"],"maxResultsPerCity": 50})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
JavaScript / Node.js (npm install apify-client):
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('batreek/us-building-permits').call({"cities": ["austin", "seattle"], "daysBack": 7, "keywords": ["solar", "roof"], "maxResultsPerCity": 50});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
AI agents (MCP): add this Actor as a tool in Claude, ChatGPT, Cursor or any MCP client through Apify's hosted MCP server at https://mcp.apify.com?tools=batreek/us-building-permits. The agent can then pull fresh construction permits for a city or trade and read the structured results. Runs are billed to your Apify account like any other run.
No-code: use Apify's integrations (Zapier, Make, n8n, Google Sheets, Slack, webhooks) or put it on an Apify Schedule.
Tips
- Schedule it daily with
daysBack: 2to get a rolling feed of new permits without duplicates piling up. - Combine
keywords+minValuationto get high-value leads only. - Valuation is what the applicant reported to the city; some permit types (e.g. electrical, signage) often report $0 or nothing.
Data, privacy & legality
This Actor only reads public open-data APIs that cities publish for reuse. It deliberately does not output personal data: owner, applicant and contact names, phone numbers and emails are dropped, even in raw mode. Only business names explicitly published as contractor/company fields are kept. Check each city's open-data terms for your use case.
FAQ
How fresh is the data? As fresh as each city's portal — most update daily.
Why are some fields empty? Not every city publishes every field (e.g. Chicago does not publish ZIP codes in this dataset).
Can I get historical permits? Yes, set issuedAfter to any date; history depth depends on the city.