Building Permits Scraper — Roofing & Construction Leads avatar

Building Permits Scraper — Roofing & Construction Leads

Pricing

from $1.60 / 1,000 permit records

Go to Apify Store
Building Permits Scraper — Roofing & Construction Leads

Building Permits Scraper — Roofing & Construction Leads

Scrape building permits and contractor leads from 120 official open-data datasets in 97 US and Canadian cities and counties (NYC, Chicago, LA, Seattle, Toronto, Calgary, more), incl. electrical, HVAC, plumbing, roof and solar permits. Contractor name, license, phone where published. $0.002/permit.

Pricing

from $1.60 / 1,000 permit records

Rating

0.0

(0)

Developer

Owlabee

Owlabee

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

2 days ago

Last modified

Features

Limited permissions

Share

Building Permits Scraper — Roofing & Construction Leads: banner with the main output fields

This Actor gives you a list of recent building permits for the US and Canadian cities you choose, with the address, the type of work, the job value, and the contractor and property owner wherever the city publishes them. It is built for roofing, solar, HVAC, electrical and remodeling contractors, suppliers and sales teams who want a lead list of who is building what, by city and date range.

Try it: press Start with the prefilled input and in about 10 seconds you get the 20 newest permits issued in Chicago in the last 7 days, with contractor names, owners and job values, for a few cents.

What you get

One record per permit, ready to download as Excel, CSV or JSON. A real record from the prefilled Chicago run (trimmed):

{
"jurisdictionName": "Chicago, IL",
"permitNumber": "B200518292",
"permitSubtype": "Mechanical Work",
"workDescription": "DUCTWORK EXTENSION/RECONFIGURATION, REPAIR/REPLACEMENT AFFECTING 1 SYSTEMS : 1 ROOFTOP PACKAGED UNIT ...",
"status": "ACTIVE",
"issuedDate": "2026-11-06",
"estimatedCost": 500000,
"address": "405 W SUPERIOR ST",
"city": "Chicago",
"state": "IL",
"contractorName": "ADMIRAL HEATING & VENTILATING INC",
"ownerName": "405 W SUPERIOR LLC",
"sourceUrl": "https://data.cityofchicago.org/d/ydr8-5enu"
}

To narrow it to your trade, add Permit type keywords such as roof, solar or electrical; to cover your market, pick other cities from the 97 supported (full list under Supported jurisdictions); to get only new permits every morning, turn on monitor mode. The full field list is under Output example.

What it does

Building permits scraper for contractor leads: pull building permits from 120 official open-data datasets covering 97 US and Canadian cities, counties and states (plus Socrata auto-discovery), including dedicated electrical, HVAC, plumbing, roof and solar permit datasets, and filter by permit type, such as roofing, re-roof or solar, and by date. Each record carries the address and job value and, where the city publishes them, the contractor's name, license and phone; monitor mode turns it into a daily feed of new permits.

This Actor pulls building permits from the official open-data portals of 83 US and 14 Canadian cities, counties and states, 120 datasets in all (plus any other Socrata portal it can discover) and writes them into one normalized JSON schema: permit number, type and subtype, work description, status, applied / issued / finalized / expiration dates, estimated cost, address with coordinates and parcel id, contractor name, license and phone, and the owner or applicant names where the jurisdiction publishes them. Every record links back to its public source.

It talks directly to each city's Socrata (SODA), CKAN DataStore, ArcGIS REST or CARTO SQL API — no browser, no proxies, no login — so runs are fast, cheap and stable. Filter by issued-date window, permit-type keywords, work-description keyword and minimum cost, and turn on Only new permits since last run to get a daily feed of fresh permits for contractor, solar, roofing, HVAC, remodeling or real-estate lead generation. Results are available as JSON, CSV, Excel, via the Apify API, webhooks and the Apify MCP server.

Roofing contractors and suppliers: permitTypes: ["roof"] (or "re-roof") over a 7-day window is a weekly re-roof lead list for a city, and monitor mode turns it into a daily feed of new roofing permits; see the Chicago and Miami-Dade task examples.

For a US city that is not in the list, turn on Discover Socrata datasets and give the place name; the Actor searches the Socrata catalog for its permit dataset and maps the columns itself. For a city that runs an Accela or EnerGov portal, Accela Citizen Access & EnerGov Permit Scraper (Any City) reads the portal directly.

Why this Actor

This ActorTypical scraper in this categoryDo it yourself
Data sources covered82 US cities and counties, one state (New Jersey) and 14 Canadian cities and regions, 120 datasets including trade-permit datasets, through their official open-data APIs (Socrata, CKAN, ArcGIS, CARTO), every entry verified live and dated, plus Socrata auto-discovery for other US placesA handful of large cities, often scraped from the permit portal's web pages; more cities on requestOne API client and one field mapping per portal, kept current as datasets move
ModesOne-off export with date, type, keyword and cost filters, and monitor mode that emits only permits not seen beforeExport with a date range; new-only is sometimes a flag with no stated memoryKeep your own seen-set per jurisdiction and prune it
Output fieldsOne normalized record: permit number, type and subtype, description, status, four dates, estimated cost, address with coordinates and parcel id, contractor name, license and phone, owner and applicant, source link; optional raw rowA normalized subset, often without parcel id, coordinates or contractor licenseWhatever you map per portal
Pricing unitPer permit record, per jurisdiction crawled and per results page fetched; an error item costs the same as a permitPer permit, usually several times more per thousand, sometimes bundled with lead scoringYour time plus compute; the portals are free
Proxies or browsers neededNoneBrowser automation and proxies when the portal UI is scrapedNone for open-data APIs
Agent / MCP readyYes: pay-per-event, limited permissions, pin link, prompts and a call example belowSometimesYou write and host the tool definition
LimitsCoverage is what each jurisdiction publishes (some omit cost or contractor); time budget per jurisdiction; barren-page stop when a filter can only be applied after downloadVaries; often no stated budget or stop ruleRate limits, pagination and outages are yours to handle
  • The cheapest per-record price in this category, and every record is open data from the jurisdiction itself with a link back to the source row.
  • Filters are pushed to the portal where it supports them and re-applied locally, so permitTypes, keyword and minEstimatedCost behave the same on every source.
  • Monitor mode is a lead feed: schedule it daily with a webhook and only new permits arrive, each flagged isNew: true.
  • Every page requested, empty or failed, is a visible charge, and a portal outage becomes one charged error item instead of a failed run.
  • The quick-start input is the Store's daily automated test against a live portal, so breakage is caught the same day.

How to use

  1. Pick one or more Jurisdictions (or a group: the 61 original US jurisdictions, all US jurisdictions, or all Canadian ones) and set Issued within (days).
  2. Optionally narrow with Permit type keywords (e.g. roof, solar, electrical), a Work description keyword (e.g. kitchen), a Minimum estimated cost, and cap Max permits per jurisdiction.
  3. Click Start. Permits appear in the dataset as each jurisdiction is paged. For a daily feed, schedule the Actor with Only new permits since last run enabled and add a Webhook URL.

Quick start input

The same input the Store runs in its daily automated test, so it is cheap and always available; paste it into the JSON tab of the input form or send it as the body of an API or MCP call:

{
"jurisdictions": [
"chicago"
],
"issuedWithinDays": 7,
"maxResultsPerJurisdiction": 20,
"onlyNewSinceLastRun": false,
"includeRaw": false
}

Ready-to-run inputs

Three inputs you can paste as they are; each validates against the input schema.

Weekly re-roof lead list for Chicago

{
"jurisdictions": ["chicago"],
"issuedWithinDays": 7,
"permitTypes": ["roof", "re-roof"],
"maxResultsPerJurisdiction": 500,
"onlyNewSinceLastRun": false,
"includeRaw": false
}

Daily monitor: new roofing and solar permits in three cities, POSTed to a webhook (schedule daily; the first run is the baseline)

{
"jurisdictions": ["austin", "raleigh", "philadelphia"],
"issuedWithinDays": 14,
"permitTypes": ["roof", "solar"],
"maxResultsPerJurisdiction": 1000,
"onlyNewSinceLastRun": true,
"stateStoreName": "permits-roof-solar-daily",
"webhookUrl": "https://example.com/hooks/permits"
}

Larger projects in New York City over the last 30 days

{
"jurisdictions": ["nyc"],
"issuedWithinDays": 30,
"minEstimatedCost": 250000,
"maxResultsPerJurisdiction": 1000,
"includeRaw": false
}

Input

FieldTypeRequiredDescription
jurisdictionsstring[]yesRegistry ids (see the tables below) or a group: all (the 61 original US jurisdictions; this list does not grow, so a saved input keeps its cost), all-us (every US entry, including the November 2026 additions and the trade-permit datasets) or all-canada. Default ["chicago","seattle"]. May be empty when discovery is on.
discoverSocratabooleannoSearch the Socrata catalog for the building-permit dataset of discoveryPlace and crawl it (see "Socrata auto-discovery"). Default false.
discoveryPlacestringnoCity or county to discover, optionally with the state: "Cook County, IL".
maxDiscoveredDatasetsintegernoDiscovered datasets to crawl, best match first (1–5). Default 2.
issuedWithinDaysintegernoOnly permits issued in the last N days (1–3650). Default 30.
permitTypesstring[]noKeep permits whose type/subtype contains any of these words (case-insensitive).
keywordstringnoKeep permits whose work description contains this text.
minEstimatedCostintegernoDrop permits with a declared cost below this, in the record's own currency (USD in the US, CAD in Canada; never converted). Permits without a cost are kept.
maxResultsPerJurisdictionintegernoCap per jurisdiction, newest first. Default 1000.
maxSecondsPerJurisdictionintegernoTime budget per jurisdiction in seconds (default 900, 60 to 3600); see "Limits and fair use".
onlyNewSinceLastRunbooleannoMonitor mode: emit only permits not seen in earlier runs (per jurisdiction, up to 50,000 remembered).
stateStoreNamestringnoNamed key-value store for the seen-sets. Default building-permits-scraper-state.
includeRawbooleannoAttach the untouched source row as raw.
socrataAppTokenstring (secret)noOptional Socrata app token to raise rate limits on the Socrata-backed portals.
webhookUrlstringnoPOST target for the run summary + emitted permits (max 500).

Filters are pushed to the server wherever the portal supports it (Socrata $where, ArcGIS where, CARTO SQL) and always re-applied client-side, so behaviour is identical across APIs. CKAN portals (Boston, Pittsburgh, Toronto, Montréal, Québec City) have no date filter: they are scanned newest-first until the window ends; San Jose publishes a rolling 30-day resource that is scanned whole. San Antonio moved from its CKAN resource to the City's ArcGIS copy of the same table in November 2026, so its filters now run on the server.

Output example

Sample output of Building Permits Scraper — Roofing & Construction Leads as a table: the dataset overview columns from the quick-start run

{
"jurisdiction": "nyc",
"jurisdictionName": "New York City, NY",
"permitNumber": "B01186301-S6-MS",
"permitType": "Mechanical Systems",
"permitSubtype": "Initial Permit",
"workDescription": "Mechanical Systems filed in conjunction to NB application #B01186301-I1.",
"status": "Permit Issued",
"appliedDate": "2026-02-20",
"issuedDate": "2026-10-14",
"finalizedDate": null,
"expirationDate": "2027-10-14",
"estimatedCost": null,
"address": "280 BERGEN STREET",
"city": "Brooklyn",
"state": "NY",
"zip": "11217",
"country": "US",
"parcelId": "3003880020",
"latitude": 40.683782,
"longitude": -73.982946,
"contractorName": "DEVELOPING NY STATE LLC",
"contractorLicense": "612632",
"contractorPhone": null,
"ownerName": "DEVELOPING NY STATE",
"applicantName": "YITCHOK KATZ",
"sourceApi": "socrata",
"sourceUrl": "https://data.cityofnewyork.us/d/rbx6-tga4",
"sourceRecordId": "B01186301-S6-MS-1",
"fetchedAt": "2026-10-16T13:25:32.995Z"
}

Dates are ISO-8601 as published (date-only when the portal stores midnight). country is "US" or "CA"; estimatedCost is a number in the local currency (USD for US records, CAD for Canadian ones, never converted) or null when the jurisdiction publishes no valuation (DC, Philadelphia, Maricopa County and others marked "no cost column" below). Canadian records hold the province code in state and the postal code (or, for Toronto, its first three characters) in zip. In monitor mode every emitted permit carries isNew: true. A jurisdiction that cannot be queried produces one error item instead of failing the run: { "jurisdiction": "boston", "error": "HTTP_503", "errorMessage": "...", "sourceApi": "ckan", "fetchedAt": "..." }.

If the output saves you time, a review on the Store page helps other buyers find this Actor; the Store invites you to leave one after you have run it a few times.

Alerts and delivery

Monitor mode is built for a daily schedule; this is how new permits reach your CRM or inbox.

  • Schedule in the Console. Save the input (with onlyNewSinceLastRun: true) as a Task, then create a schedule under Schedules (daily is the natural cadence, since most portals refresh once a day) and attach the Task. Use one stateStoreName per schedule when different filters run against the same jurisdiction.
  • The Actor's own webhook. Set webhookUrl and the Actor POSTs one JSON document at the end of every run, including runs that found nothing new (10 second timeout, two retries; a failed delivery is recorded as webhookDelivered: false in the SUMMARY record and never fails the run). The body is the run summary (actor, runId, produced, permitsSaved, errors, jurisdictions, issuedWithinDays, monitor, perJurisdiction with fetched, saved and page counts per id, charges, limitReached, finishedAt) plus permits, the first 500 emitted permit records in dataset shape, and errorItems for jurisdictions that failed. Larger runs continue in the dataset.
  • Apify run webhooks. On the Actor's Integrations tab add a webhook for run events such as ACTOR.RUN.SUCCEEDED, ACTOR.RUN.FAILED or ACTOR.RUN.TIMED_OUT; Apify POSTs the run id and the default dataset id to your URL, which is all your own code needs to fetch the items.
  • Slack, Make, Zapier, Google Sheets, email. The same Integrations tab lists Apify's ready-made integrations: a Slack message when a run finishes, Make and Zapier modules that start runs and read the dataset, an export of each run's dataset to a Google Sheet, and an email notification. They are configured per Actor or per task, without code.
  • API and dataset endpoints. Start a run with POST https://api.apify.com/v2/acts/owlabee~building-permits-scraper/runs, read the newest results with GET https://api.apify.com/v2/acts/owlabee~building-permits-scraper/runs/last/dataset/items?format=json (also csv or xlsx, and fields to pick columns), or read any run's dataset at https://api.apify.com/v2/datasets/<datasetId>/items. For short runs run-sync-get-dataset-items starts the run and returns the items in one call.

Supported jurisdictions

120 entries in four groups: the 61 original US entries (the all group), 14 trade-permit datasets in cities already covered, 27 more US entries and 18 Canadian ones. The first 26 were verified live on 2026-10-16, the next 35 on 2026-10-28 and the other 59 on 2026-11-07 (dataset id, field mapping, freshness of the newest issued date; real rows from each are kept as test fixtures). "Contractor, license, phone" means the jurisdiction publishes those columns; nothing is inferred.

Original US jurisdictions (all)

IdJurisdictionSource (API)Update frequency / notes
nycNew York City, NYDOB NOW: Build – Approved Permits rbx6-tga4 (Socrata)Daily. Electronic DOB NOW filings; cost, contractor license, owner.
chicagoChicago, ILBuilding Permits ydr8-5enu (Socrata)Daily. Contractor/owner/applicant from contact roles.
los-angelesLos Angeles, CALADBS Permits Issued 2020–present pi9x-tg5x (Socrata)Weekly; issued dates lag ~1 week. No contractor/owner columns.
san-franciscoSan Francisco, CADBI Building Permits i98e-djp9 (Socrata)Daily. One row per permit address.
seattleSeattle, WASDCI Building Permits 76t5-zqzr (Socrata)Daily. Per-record portal links.
austinAustin, TXIssued Construction Permits 3syk-w9eu (Socrata)Daily. Contractor + applicant, per-record links.
philadelphiaPhiladelphia, PAL&I Permits (CARTO SQL, OpenDataPhilly)Daily. Contractor + OPA owner; no valuation.
bostonBoston, MAApproved Building Permits (CKAN DataStore)Daily. Applicant, declared valuation.
washington-dcWashington, DCDCRA Building Permits in {year} (ArcGIS)Daily. Layer per calendar year, resolved at run time; no valuation.
miami-dade-countyMiami-Dade County, FLPermits issued by the County, 2 previous years to present (ArcGIS)Daily. County-issued permits (unincorporated areas), no coordinates.
maricopa-county-azMaricopa County, AZBuilding Permits (ArcGIS)Daily. Unincorporated county only; no valuation.
nashvilleNashville / Davidson County, TNBuilding Permits Issued (ArcGIS)Daily.
detroitDetroit, MIBSEED Building Permits (ArcGIS)Daily. No status/contractor columns.
raleighRaleigh, NCBuilding Permits (ArcGIS)Daily. Contractor, parcel owner.
baltimoreBaltimore, MDDHCD Building Permits (ArcGIS)Every 2–4 weeks; issued dates lag up to a month.
cincinnatiCincinnati, OHBuilding Permits uhjb-xac9 (Socrata)Daily. Per-record links.
pittsburghPittsburgh, PAPLI Permits (CKAN DataStore, WPRDC)Daily. Contractor + owner when published.
louisvilleLouisville / Jefferson County, KYActive Construction Permits (ArcGIS)Daily. Active permits only; no free-text description.
memphisMemphis / Shelby County, TNDPD Building Permits (ArcGIS)~Every 2 weeks; issued dates lag up to ~3 weeks.
new-orleansNew Orleans, LAOne Stop Permits rcm3-fn58 (Socrata)Daily. Contractor, owner, applicant.
tucsonTucson, AZResidential Permits (ArcGIS)Daily. Residential layer only.
buffaloBuffalo, NYPermits 9p2d-f3yt (Socrata)Daily. Applicant + license number.
orlandoOrlando, FLPermit Applications ryhf-m453 (Socrata)Daily refresh; issued dates lag ~3 weeks. Contractor + owner.
montgomery-county-md-residentialMontgomery County, MDResidential Permits m88u-pqki (Socrata)Daily.
montgomery-county-md-commercialMontgomery County, MDCommercial Permits i26v-w6bd (Socrata)Daily.
cambridge-maCambridge, MABuilding Permits: Addition/Alteration qu2z-8suj (Socrata)Daily. Applicant + contractor firm.
mesaMesa, AZcitydata.mesaaz.gov dzpk-hxfb (Socrata)Daily. Contractor, license, phone, applicant.
san-diego-countySan Diego County, CA (unincorporated)data.sandiegocounty.gov red2-qccu (Socrata)Daily. Contractor, phone.
marin-countyMarin County, CAdata.marincounty.gov mkbn-caye (Socrata)Daily. Contractor, license.
baton-rougeBaton Rouge / East Baton Rouge Parish, LAdata.brla.gov 7fq7-8j7r (Socrata)Daily. Contractor, owner, applicant.
norfolkNorfolk, VAdata.norfolk.gov fahm-yuh4 (Socrata)Daily.
pierce-county-waPierce County, WA (unincorporated)open.piercecountywa.gov nhnt-v7ka (Socrata)Daily (weekdays).
everettEverett, WAdata.everettwa.gov 3w3u-656c (Socrata)Daily. Contractor, owner, applicant.
somerville-maSomerville, MAdata.somervillema.gov nneb-s3f7 (Socrata)Daily. Contractor, applicant.
college-stationCollege Station, TXdata.cstx.gov hrbn-znt6 (Socrata)Daily (weekdays).
corona-caCorona, CAcorstat.coronaca.gov 2agx-camz (Socrata)Weekly (issued dates lag up to ~2 weeks).
prince-georges-countyPrince George's County, MDdata.princegeorgescountymd.gov weik-ttee (Socrata)Monthly (issued dates lag up to ~5 weeks; use issuedWithinDays ≥ 45).
urbana-ilUrbana, ILillinois-edp.data.socrata.com dvw9-7wyx (Socrata)Monthly (use issuedWithinDays ≥ 45). Applicant.
new-jerseyNew Jersey (statewide, all municipalities)data.nj.gov w9se-dmra (Socrata)Every 1–3 months (DCA Construction Reporter; newest permits lag ~2–3 months; use issuedWithinDays ≥ 120).
collin-county-txCollin County, TX (appraisal district permit feed)data.texas.gov 82ee-gbj5 (Socrata)Daily refresh; permits arrive as the cities report them to the appraisal district (lag of days to weeks). Contractor, owner.
denver-residentialDenver, CO (residential construction)ODC DEV RESIDENTIALCONSTPERMIT P (ArcGIS)Daily. Contractor.
denver-commercialDenver, CO (commercial construction)ODC DEV COMMERCIALCONSTPERMIT P (ArcGIS)Daily. Contractor.
columbusColumbus, OHBuilding Permits (ArcGIS)Daily. Applicant.
charlotte-mecklenburgCharlotte / Mecklenburg County, NCBuildingPermits (ArcGIS)Daily. Owner.
fort-worthFort Worth, TXCFW Open Data Development Permits View (ArcGIS)Daily. Owner.
harris-county-txHarris County, TX (unincorporated, Houston area)ePermits (ArcGIS)Daily.
miamiMiami, FL (City of Miami)Building Permits Since 2014 (ArcGIS)Daily. Contractor.
minneapolisMinneapolis, MNCCS Permits (ArcGIS)Daily. Applicant.
clevelandCleveland, OHBuilding Permits (ArcGIS)Daily (pages are slow: about 10 s per 1,000 rows). Contractor, license.
wake-county-ncWake County, NCBuilding Permits (ArcGIS)Daily. Contractor.
durhamDurham / Durham County, NCInspections (ArcGIS)Daily.
anaheimAnaheim, CAAccela Building Permits (ArcGIS)Daily. Contractor, phone.
tempeTempe, AZbuilding permits (ArcGIS)Daily. Contractor, license, phone.
scottsdaleScottsdale, AZOpenData Tabular (ArcGIS)Weekly. Contractor, owner, applicant.
bellevue-waBellevue, WABellevue Permits (Pending - Ready to Issue - Issued - Open) (ArcGIS)Daily. Contractor, owner, applicant.
forsyth-county-gaForsyth County, GABuilding Permits (ArcGIS)Daily.
charleston-scCharleston, SC (new construction)New Construction Permits (ArcGIS)Nightly (EnerGov export).
portland-orPortland, OR (residential new construction)COP OpenData PlanningDevelopment (ArcGIS)Weekly (issued dates lag up to ~4 weeks; use issuedWithinDays ≥ 45).
las-vegasLas Vegas, NVOpenData Building Permits (ArcGIS)Monthly (issued dates lag up to ~4 weeks; use issuedWithinDays ≥ 45). Owner, applicant.
san-antonioSan Antonio, TXPermits Issued (ArcGIS; was CKAN until 2026-11)Daily. Applicant.
san-joseSan Jose, CAdata.sanjoseca.gov (CKAN)Daily (rolling 30-day window: older permits are not in this feed). Contractor, ### Trade-permit datasets in covered cities (added 2026-11)

Electrical, mechanical (HVAC), plumbing, roof and solar permits that the city publishes as separate datasets. Each is its own id, so add it next to the city's main entry (for example ["seattle", "seattle-electrical", "seattle-trade"]). Austin, New Orleans and Cleveland need no extra id: their main entries already include electrical, mechanical and plumbing permits.

IdJurisdictionSource (API)Update frequency / notes
los-angeles-electricalLos Angeles, CA (electrical permits)data.lacity.org ysqd-apz7 (Socrata)Weekly (LADBS refresh; issued dates lag ~1 week).
los-angeles-mechanicalLos Angeles, CA (mechanical, HVAC and plumbing permits)data.lacity.org 67is-svtd (Socrata)Weekly (LADBS refresh; issued dates lag ~1 week).
seattle-tradeSeattle, WA (trade permits: mechanical, plumbing, gas)cos-data.seattle.gov c87v-5hwh (Socrata)Daily. Contractor.
seattle-electricalSeattle, WA (electrical permits)cos-data.seattle.gov c4tj-daue (Socrata)Daily. Contractor.
nyc-electricalNew York City, NY (DOB NOW electrical permits)data.cityofnewyork.us dm9a-ab7w (Socrata)Daily. Contractor, license, owner, applicant, no cost column.
montgomery-county-md-electricalMontgomery County, MD (electrical)data.montgomerycountymd.gov qxie-8qnp (Socrata)Daily.
montgomery-county-md-mechanicalMontgomery County, MD (mechanical / HVAC)data.montgomerycountymd.gov ih88-a6aa (Socrata)Daily.
cambridge-ma-roofCambridge, MA (roof permits)data.cambridgema.gov 79ih-g44d (Socrata)Daily. Contractor, license, applicant.
cambridge-ma-solarCambridge, MA (solar permits)data.cambridgema.gov whpw-w55x (Socrata)Daily. Contractor, applicant.
cambridge-ma-electricalCambridge, MA (electrical permits)data.cambridgema.gov hvtc-3ab9 (Socrata)Daily. Contractor, applicant.
cambridge-ma-plumbingCambridge, MA (plumbing permits)data.cambridgema.gov 8793-tet2 (Socrata)Daily. Contractor, applicant, no cost column.
cambridge-ma-mechanicalCambridge, MA (mechanical / HVAC permits)data.cambridgema.gov 4rb4-q8tj (Socrata)Daily. Contractor, applicant, no cost column.
nashville-tradeNashville / Davidson County, TN (trade permits)Trade Permits View (ArcGIS)Weekly to every few weeks (issued dates lag 2 to 9 weeks; use issuedWithinDays ≥ 60). Applicant.
raleigh-tradeRaleigh, NC (trade and other non-building permits)Permits Other Than Buildings (ArcGIS)Daily. Contractor, phone, no cost column.

More US jurisdictions (added 2026-11)

IdJurisdictionSource (API)Update frequency / notes
tacoma-waTacoma, WAaccela permit data (ArcGIS)Daily. Applicant.
henderson-nv-residentialHenderson, NV (residential dwellings)OpenDevPermits (ArcGIS)Daily. Owner, no cost column.
henderson-nv-otherHenderson, NV (other building permits)OpenDevPermits (ArcGIS)Daily. Owner, no cost column.
cape-coral-flCape Coral, FLOpenData (ArcGIS)Daily. Contractor.
baltimore-county-mdBaltimore County, MD (building permits)ActiveDevelopment (ArcGIS)Daily. Contractor, owner.
baltimore-county-md-electricalBaltimore County, MD (electrical permits)ActiveDevelopment (ArcGIS)Every few weeks (issued dates lag 2 to 9 weeks; use issuedWithinDays ≥ 60). Contractor, owner, no cost column.
baltimore-county-md-plumbingBaltimore County, MD (plumbing permits)ActiveDevelopment (ArcGIS)Every few weeks (issued dates lag 2 to 9 weeks; use issuedWithinDays ≥ 60). Contractor, owner, no cost column.
allentown-paAllentown, PAEnerGov Building Permits Current (ArcGIS)Daily. No cost column.
bend-orBend, ORPermitting Table (ArcGIS)Daily. Owner.
overland-park-ksOverland Park, KSBuilding Permits (ArcGIS)Daily.
tyler-txTyler, TXPermit Data With XY (ArcGIS)Monthly (the newest issued date lags up to a month; use issuedWithinDays ≥ 45). Contractor, owner, applicant.
st-charles-ilSt. Charles, ILStCharlesPermitData (ArcGIS)Daily.
placentia-caPlacentia, CABuilding Permit Points (ArcGIS)Monthly batches (one sheet per month). Applicant.
campbell-caCampbell, CACampbellPermits (ArcGIS)Daily. No cost column.
atascadero-caAtascadero, CAPermits public (ArcGIS)Daily. No cost column.
elk-grove-caElk Grove, CATRAKiT Building Permits (ArcGIS)Daily. Contractor, phone.
hutto-txHutto, TXCity of Hutto Building Permits 2026 2027 (ArcGIS)Daily. No cost column.
san-marcos-txSan Marcos, TXCoSM BuildingPermits (ArcGIS)Daily. No cost column.
tallahassee-leon-sfTallahassee / Leon County, FL (single-family new construction)TLC OverlayPermitsActiveTrends D WM (ArcGIS)Daily. Contractor, license, phone.
normal-ilNormal, ILPermits Public (ArcGIS)Daily. Contractor, owner.
morgantown-wvMorgantown, WVqe (ArcGIS)Daily. No cost column.
cody-wyCody, WYqe (ArcGIS)Daily. No cost column.
weston-flWeston, FLIssuedPermitReport (ArcGIS)Daily.
benton-county-waBenton County, WA (unincorporated)Building Permits Assessor VIew (ArcGIS)Daily. Owner, applicant.
fulton-county-ohFulton County, OHPermits Recent Public View (ArcGIS)Daily. Contractor.
talent-orTalent, ORTalent Building Permits View (ArcGIS)Weekly. Owner.
cook-county-ilCook County, IL (assessor permit feed, all municipalities)datacatalog.cookcountyil.gov 6yjf-dfxs (Socrata)Daily, but permits reach the assessor weeks after issue (use issuedWithinDays ≥ 60). Applicant.

Canada (added 2026-11)

Canadian records carry country: "CA", the province code in state and costs in CAD. Party names are business names only: an owner, applicant or contractor value is kept when it reads as a business (a company suffix such as Ltd, Inc or Ltée, or a trade word such as Construction, Plumbing or Homes) and is null otherwise; values that list several parties keep only their business parts, and the same rule applies to the raw row, from which town-staff and contractor-address columns are removed. A company name without such a word is left out too. This follows the 2026-11 legal review of Canadian privacy law (PIPEDA s. 7 with SOR/2001-7 s. 1(c); Québec's Law 25): individual names are withheld, business names are kept, and there is no input that changes it (see "Legal"). Montréal and Québec City publish text in French, as kept here.

Sources and licences: contains information licensed under the Open Government Licence – Toronto, the Open Government Licence – City of Calgary, the Open Government Licence – City of Edmonton and the Open Government Licence – Winnipeg; Montréal and Québec City data is published under CC BY 4.0 by the Ville de Montréal and the Ville de Québec (via Données Québec); the other Canadian entries are the municipalities' own open-data layers.

IdJurisdictionSource (API)Update frequency / notes
toronto-onToronto, ONckan0.cf.opendata.inter.prod-toronto.ca (CKAN)Daily. Contractor (business names only).
montreal-qcMontréal, QCwww.donneesquebec.ca (CKAN)Daily. No cost column.
quebec-city-qcQuébec City, QCwww.donneesquebec.ca (CKAN)Daily. No cost column.
calgary-abCalgary, AB (building permits)data.calgary.ca c2es-76ed (Socrata)Daily. Contractor and applicant (business names only).
calgary-ab-electricalCalgary, AB (electrical permits)data.calgary.ca vxgy-id5s (Socrata)Daily. Contractor and applicant (business names only), no cost column.
calgary-ab-mechanicalCalgary, AB (HVAC / mechanical permits)data.calgary.ca cdrc-r4u8 (Socrata)Daily. Contractor and applicant (business names only), no cost column.
calgary-ab-plumbingCalgary, AB (plumbing and gas permits)data.calgary.ca 5pvv-k7hn (Socrata)Daily. Contractor, no cost column.
edmonton-abEdmonton, ABdata.edmonton.ca 24uj-dj8v (Socrata)Daily. No permit number is published (permitNumber null, sourceRecordId is the row id).
winnipeg-mbWinnipeg, MB (building permits)data.winnipeg.ca it4w-cpf4 (Socrata)Daily. Applicant (business names only), no cost column.
winnipeg-mb-tradeWinnipeg, MB (trade permits: electrical, plumbing, mechanical)data.winnipeg.ca urbd-qygv (Socrata)Daily. Applicant (business names only), no cost column.
halifax-nsHalifax Regional Municipality, NSPPLC Issued Building Permits (ArcGIS)Daily.
kitchener-onKitchener, ONBuilding Permits (ArcGIS)Daily. Contractor, owner and applicant (business names only).
new-westminster-bcNew Westminster, BCPermits Buildings (ArcGIS)Daily. Contractor (business names only).
prince-george-bcPrince George, BCBuilding Permit Applications (ArcGIS)Daily.
squamish-bcSquamish, BCBuilding Permits (ArcGIS)Daily. Applicant (business names only).
caledon-onCaledon, ONMiscLayers (ArcGIS)Daily.
whitchurch-stouffville-onWhitchurch-Stouffville, ONBuildingPermits Points (ArcGIS)Daily.
miramichi-nbGreater Miramichi Regional Service Commission, NBPermit Applications 2026 (ArcGIS)Daily.

owner, applicant. |

For lagging feeds (Baltimore, Memphis, Orlando, Los Angeles, Corona, Portland, Las Vegas, Prince George's County, Urbana, Tyler) use issuedWithinDays of 30–45, and 60 for Nashville trade permits, Baltimore County's electrical and plumbing layers and the Cook County assessor feed, so the window overlaps the publication delay; New Jersey's statewide feed lags about 11 weeks, so use 120 or more. County entries cover county-issued permits (usually the unincorporated area), not the cities inside them, unless the notes say otherwise. Fort Worth publishes the filing date only, so its window runs on the filing date; Prince George, BC's window runs on the approval date. Hutto (by fiscal year) and Miramichi (by calendar year) start a new dataset every year; the Actor finds the newest one at run time, so a window that crosses the changeover only sees the new year. Not included on purpose: Dallas (text dates that cannot be filtered on the server), Kansas City, Honolulu, Phoenix and Sonoma County (feeds stopped updating in 2023–2025), Virginia Beach (not updated since July 2026), the NYC legacy BIS feed (free-text dates, 15–30 s queries), Houston city, San Diego city, Indianapolis and Tampa (no no-login permit API found; Harris County and San Diego County are covered), Atlanta (its open-data permit layer holds applications under review, records requests and temporary-power permits, not issued building permits), Roseville, CA (no address, parcel or coordinate column), Greensboro (its layer failed with a server error on 2026-11-07), Tucson's all-permits layer (newest permit 2026-09-26) and Vancouver (its open-data API reset our connection on 2026-11-07; it will be added once a run can reach it without a workaround).

Socrata auto-discovery

For a place that is not in the table, set discoverSocrata: true and discoveryPlace (for example "Cook County, IL"). The Actor sends one request to the public Socrata Discovery API (no key), keeps current datasets whose name says "permit" (not parking, events, trees, signs, wells, licenses or inspections) and whose portal names the place, maps their columns by name (permit number, issue date, address, type, description, valuation, contractor, license, phone, owner, applicant, coordinates) and crawls the best maxDiscoveredDatasets like built-in jurisdictions, with the same time budget and filters.

  • Every record from a discovered dataset carries mappingConfidence: high (permit number, an issue-date column, address and a type or description), medium (issue date plus some of those), or low (no column named for the issue date, so the date window runs on another date column). It also carries discoveredDataset (domain/id). The run's SUMMARY lists the matched columns.
  • A place that is already built in returns the built-in entry, with its hand-checked mapping.
  • Discovery searches Socrata portals only. Many cities publish on ArcGIS or CKAN, and some Socrata portals do not name their city in a way the search can match; when nothing is found the run writes one NO_DATASET_FOUND error item.

Monitor mode

With onlyNewSinceLastRun, the Actor keeps a seen-set of sourceRecordIds per jurisdiction in the state store (max 50,000 per jurisdiction, oldest pruned first) and emits only permits it has not seen before, flagged isNew: true. The first run is a baseline: it emits and charges for every permit in the window. Permits that drop out of the date window and reappear are not reported again. Use one state store name per schedule if you run different filters against the same jurisdiction.

Pricing

Pay per event. You only pay for what the Actor produces; set a maximum cost per run in the run options to cap spend.

EventPriceNotes
Permit record (permit-scraped)$0.002Per dataset item, including error items for jurisdictions that failed
Jurisdiction crawl (jurisdiction-crawled)$0.002Once per jurisdiction (or discovered dataset) per run, regardless of result count
Results page (jurisdiction-page-fetched)$0.002Per results page requested from a portal (up to 1,000 rows), including empty pages, pages whose rows were all filtered out or already seen, a request that fails or times out, and the one Socrata catalog search when discovery is on
Actor start$0.00005Apify platform event

Examples: 1,000 permits from one jurisdiction ≈ $2.00 + $0.002 + 1 results page $0.002 ≈ $2.00; a daily check of 10 cities ≈ $0.02 + 10 results pages $0.02 = $0.04 + $0.002 per new permit found. The default input (Chicago, 20 permits) costs ≈ $0.044. Monitor runs that find nothing new cost only the per-jurisdiction fee and the results page(s) fetched.

Store pricing discounts: users on the Scale plan (Silver) pay 10% less per event, Business (Gold) 20% less.

Price change of 2026-10-28: every event dropped to $0.002 (permit record from $0.003, jurisdiction crawl from $0.01, results page from $0.003).

Limits and fair use

  • Requests are rate-limited to at most 2 per second per portal, with exponential backoff on 429/5xx; three jurisdictions are crawled in parallel.
  • Page sizes are 1,000 rows; a jurisdiction with 20,000 permits in the window takes about 20 requests.
  • Time budget per jurisdiction. Each jurisdiction gets maxSecondsPerJurisdiction seconds (default 900) and is cut off earlier when 60 seconds pass without a page that yields a permit (a stalling, blocking or never-matching portal). Every request, retries included, is limited to 45 seconds and a Retry-After longer than 10 seconds is not waited for. A cut-off jurisdiction keeps the permits already fetched (truncated in the run summary); one that fetched nothing becomes a TIME_BUDGET error item, charged like every error item. When filters can only be applied after download (CKAN portals, or a keyword, permit type or minimum cost the portal cannot filter), a scan also stops after 8 consecutive pages of 1,000 rows without a single match. Separately, when permitTypes, keyword or minEstimatedCost has to be applied client-side (CKAN portals, or fields the portal cannot filter), a scan stops after 8 consecutive 1,000-row pages with no matching permit and the jurisdiction is marked truncated: "BARREN_PAGES" in the SUMMARY (the jurisdiction fee is charged, no error item): the newest 8,000 rows of the window held nothing that matched. To look further back, narrow issuedWithinDays so the window ends inside those rows, or use a filter the portal applies server-side; every scanned page costs transfer that no permit pays for.
  • Default run memory is 512 MB; records are held in memory per jurisdiction, so very large maxResultsPerJurisdiction values with many jurisdictions may need more.
  • Only public open-data endpoints are used. No login, no proxies, no browsers. Socrata portals allow anonymous use; add a free app token for heavy daily use.
  • Each portal defines its own permit-type vocabulary; use generic words in permitTypes and check permitType/permitSubtype values in a first run.
  • Coverage is the jurisdiction's own dataset: county entries cover county-issued permits, Louisville publishes active permits only, Tucson residential only, Tallahassee / Leon County single-family new construction only; the Cook County entry is the assessor's copy of every municipality's permits, which arrives weeks after issue.
  • Toronto, Montréal and Québec City are CKAN portals without a server-side date filter, so each run downloads at least one page of 1,000 rows (about 2.6 MB for Toronto) even when maxResultsPerJurisdiction is small.

Other pay-per-event Actors from the same account, all limited-permission and agent-friendly:

Guide and code examples

Use from AI agents (MCP)

Pin this Actor in the Apify MCP server with one link: https://mcp.apify.com?tools=owlabee/building-permits-scraper, or let the agent find it with the search-actors tool. It is pay-per-event with limited permissions, so agents can discover it, inspect the input schema with fetch-actor-details and pay per run through agentic payments. Prompts that map directly onto the input:

  1. "List the building permits issued in Chicago and Seattle in the last 7 days with an estimated cost above fifty thousand dollars, including the contractor and address."
  2. "Every morning, find new roofing and solar permits in Austin, Raleigh and Philadelphia (only ones not seen before) and POST them to my CRM webhook."
  3. "Which contractors pulled the most residential permits in Montgomery County, MD over the last 30 days, and what kinds of work were they for?"

The agent receives the same dataset records shown in the output example above.

To call it from an agent that already has the Apify MCP server connected, copy this tool call and change only the input object (shown with the quick-start input; any input that validates in the Console works here too). The server returns the run's dataset items, and its per-call maximum total charge (maxTotalChargeUsd) caps spend the same way the run option does in the Console.

{
"tool": "call-actor",
"arguments": {
"actor": "owlabee/building-permits-scraper",
"input": {
"jurisdictions": [
"chicago"
],
"issuedWithinDays": 7,
"maxResultsPerJurisdiction": 20,
"onlyNewSinceLastRun": false,
"includeRaw": false
}
}
}

FAQ

Does this need proxies or an API key? No. It calls public open-data APIs over plain HTTPS from Apify's standard infrastructure. A Socrata app token is optional and only raises rate limits.

How is cost controlled? Set maxResultsPerJurisdiction, narrow issuedWithinDays and filters, and set the run's maximum total charge; the Actor stops cleanly when any limit is reached. In monitor mode you pay per new permit only.

Why does a permit have estimatedCost: null or no contractor? The jurisdiction does not publish that column (see the table). Turn on includeRaw to see every field the portal does publish.

Can I get only solar or roofing permits? Yes: permitTypes: ["solar","roof"] and/or keyword: "solar". Type filters match the portal's type and subtype labels; the keyword matches the free-text work description, which is where most solar/re-roof jobs are described.

Can I run it on a schedule or from an AI agent? Yes — Apify Schedules, the API, or the Apify MCP server. The Actor is pay-per-event and uses limited permissions, so agents can discover and call it. Example prompts: "List building permits issued in Chicago this week with an estimated cost over $50,000", "Every morning send me new roofing permits in Austin and Raleigh", "Which contractors pulled the most solar permits in Philadelphia in the last 30 days?".

What happens when a city portal is down? That jurisdiction yields one error item (charged like a permit) and the rest of the run continues; the daily Store test therefore never fails on a single portal outage.

Does it cover Canada? Yes: Toronto, Montréal, Calgary, Edmonton, Winnipeg, Québec City, Halifax, Kitchener and six smaller cities and regions (all-canada), with costs in CAD and business names only (see "Canada" above). Vancouver is not included yet.

Do I get trade permits (electrical, HVAC, plumbing, solar, roofing)? Where the city publishes them: some cities include them in their main dataset (Austin, New Orleans and Cleveland; NYC's main entry has plumbing, mechanical and solar) and others publish separate datasets with their own ids (seattle-electrical, los-angeles-mechanical, cambridge-ma-roof, cambridge-ma-solar, calgary-ab-electrical and the rest in the trade table). Use permitTypes such as electrical, mechanical, plumbing, roof or solar to narrow any of them.

Can you add my city? Open an issue with the portal URL. Any Socrata, CKAN DataStore, ArcGIS FeatureServer/MapServer or CARTO dataset with an issued-date column can be added as a registry entry.

Can I try it for free? Yes. The Apify free plan comes with monthly platform credit, and the quick-start input above costs a few cents per run, so you can test it on your own inputs before paying anything.

How do I find this Actor again? Bookmark it on the Store page (the bookmark icon next to the title); bookmarked Actors are listed in your Console, and the Store page shows new versions as they ship.

Support

Questions, bugs or a source you'd like added? Open an issue on the Actor's Issues tab, or email jacob@owlabee.com.

Changelog

  • 2026-11-09 — README opens with what you get and who it is for, a trimmed real record and a one-click "Try it" line. The prefilled input is now Chicago only, 20 permits from the last 7 days (was Chicago and Seattle, 25 each), so the first run is faster and cheaper; the jurisdictions default for API calls is unchanged.
  • 2026-11-07 — 59 more datasets (120 in total), all opt-in: 14 trade-permit datasets in cities already covered (electrical, mechanical/HVAC, plumbing, roof and solar in Los Angeles, Seattle, NYC, Montgomery County, Cambridge, Nashville and Raleigh), 27 US entries (Tacoma, Cape Coral, Baltimore County, Henderson, Bend, Overland Park, Elk Grove, Allentown, the Cook County assessor feed for all of suburban Cook and more) and 18 Canadian ones (Toronto, Montréal, Québec City, Calgary, Edmonton, Winnipeg, Halifax, Kitchener and six smaller places). New country field on every record. all keeps its 61 jurisdictions; new groups all-us and all-canada. Canadian records carry business names only. San Antonio reads the City's ArcGIS copy of the same table, so its filters run on the server.
  • 2026-10-28 — Price decrease: permit record, jurisdiction crawl and results page all $0.002. The Socrata catalog search gives up after 20 seconds.
  • 2026-10-28 — 35 more jurisdictions (61 in total): Denver, Columbus, Charlotte, Fort Worth, San Antonio, San Jose, Miami, Minneapolis, Cleveland, Mesa, Las Vegas, Portland, Harris County, Wake County, San Diego County, statewide New Jersey and more. Socrata auto-discovery for other places, with a mapping-confidence flag on every discovered record. Contractor phone where the jurisdiction publishes it.
  • 2026-10-27 — README: comparison table, ready-to-run inputs for a re-roof lead list and a daily monitor, alerts and delivery, MCP call example, changelog.
  • 2026-10-25 — Pricing round: the results page became its own work-based event (charged for every page requested, empty or filtered out), event titles pluralized, Store discount tiers for the Scale and Business plans described; applied in the Console on 2026-10-26.
  • 2026-10-23 — Time budget per jurisdiction (maxSecondsPerJurisdiction), 45 second request deadline including retries, idle cut-off, BARREN_PAGES stop with a logged hint on how to lift it, charged TIME_BUDGET error items, worst-case margin tests. Listing: title names construction leads, SEO fields, MCP section, quick start, task examples; Related Actors use the new display titles.
  • 2026-10-19 — Roofing task examples: weekly re-roof lists and daily feeds for Chicago and Miami-Dade County.
  • 2026-10-18 — Published on the Store with its task examples.
  • 2026-10-16 — First release: 26 jurisdictions over four portal APIs, server-side plus local filters, monitor mode, end-of-run webhook with the emitted permits.

All data comes from public records published by the jurisdictions themselves under their open-data terms; this Actor does not access permit portals that require login or forbid automated access.

Not a consumer report. Not for employment, credit, insurance, housing or tenant-screening decisions. This Actor is not a consumer reporting agency and its output is not a consumer report under the Fair Credit Reporting Act (FCRA); it must not be used for employment, credit, insurance, housing or tenant screening decisions, or for any purpose that requires FCRA compliance. The same sentence travels with every run as the notice field of the SUMMARY record and the webhook body.

Names. For US jurisdictions, owner, applicant and contractor names are reproduced as published by the jurisdiction and may be stale or incomplete. For Canadian jurisdictions (country: "CA") individual owner and applicant names are withheld: only values that read as a business are emitted, in the normalized fields and in raw alike (see "Canada" above), because a permit register's public-access purpose does not extend to marketing to the homeowner under PIPEDA (s. 7 and the Regulations Specifying Publicly Available Information, SOR/2001-7 s. 1(c)) or Québec's Act respecting the protection of personal information in the private sector (Law 25); business contact information is outside those consent rules. There is no input that restores individual names, and the Actor has no search by a person's name: inputs are jurisdictions, date windows, permit types, keywords and valuation. Owner mailing addresses and contractor e-mail addresses are never top-level fields; the only contact detail emitted is the contractor's business phone where the jurisdiction publishes it.

Canadian licences and attribution. Contains information licensed under the Open Government Licence – Toronto, the Open Government Licence – City of Calgary, the Open Government Licence – City of Edmonton and the Open Government Licence – Winnipeg; Montréal and Québec City data is published under CC BY 4.0 by the Ville de Montréal and the Ville de Québec (via Données Québec); the other Canadian entries are the municipalities' own open-data layers. Keep these attributions with any redistribution of the Canadian records. The licences cover copyright in the datasets, not personal information, which is why the name rule above applies whatever the licence.

Outreach and data handling. Respect do-not-contact rules and telemarketing laws when using the records for outreach: in the US the TCPA and the National Do Not Call Registry; in Canada CASL for commercial electronic messages and the CRTC Unsolicited Telecommunications Rules. owlabee keeps no copy of the records: results exist only in your Apify storage, nothing is aggregated across runs or users, and no dataset is resold. Use the data in compliance with each source's terms and applicable law. Not affiliated with any of the cities, counties, provinces or states named; their names identify the source of the records.