US Building Permits Scraper - Construction Leads avatar

US Building Permits Scraper - Construction Leads

Pricing

from $1.50 / 1,000 permit records

Go to Apify Store
US Building Permits Scraper - Construction Leads

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

Adam Abdou-Gustavson

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

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

CitySource
Chicago, ILdata.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, CAdata.sf.gov
Seattle, WAdata.seattle.gov
Austin, TXdata.austintexas.gov
New Orleans, LAdata.nola.gov
Cambridge, MA (new construction)data.cambridgema.gov
Montgomery County, MD (residential)data.montgomerycountymd.gov
Mesa, AZdata.mesaaz.gov
Cincinnati, OHdata.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

FieldWhat it does
citiesCities to include. Empty = all.
issuedAfter / daysBackDate window (default: last 30 days).
keywordsKeep permits whose type/description mentions any keyword, e.g. solar, roof, pool, ADU.
minValuationMinimum reported project value in USD.
maxResultsPerCityCap per city, newest first.
includeRawAlso 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?

PermitsCost
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 ApifyClient
client = 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: 2 to get a rolling feed of new permits without duplicates piling up.
  • Combine keywords + minValuation to 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.