DEV Community

PerskeKits
PerskeKits

Posted on

How to Scrape Building Permits for Contractor Leads

A building permit is a clear sign that work is about to start. Someone has a project, a budget and a timeline. For roofers, solar installers, HVAC and pool companies, remodelers, material suppliers and equipment rental businesses, new permits are some of the most targeted leads around.

This guide covers where permit data comes from, why collecting it by hand is painful, and how to pull it from five major US cities with the Building Permits Scraper on Apify.

The problem

Many cities publish permits on open-data portals, but every city uses its own dataset, field names and update schedule. One city calls it "work description," another calls it "permit type," and valuation fields vary in format. Comparing or combining cities means cleaning up each source separately.

The manual way (and why it hurts)

You could visit each city's portal, filter by issue date, export a CSV, and then line up the columns in a spreadsheet. Then you'd search the descriptions for "roof" or "solar" and repeat it all next week. Some portals limit exports or time out on large date ranges, and a few publish several days late, so it's easy to miss permits.

The sources

The Actor reads official, public open-data portals that update daily:

City Portal
Chicago data.cityofchicago.org Building Permits
New York data.cityofnewyork.us DOB NOW Build Approved Permits
Los Angeles data.lacity.org Building Permits Issued 2020-present
Austin data.austintexas.gov Issued Construction Permits
Seattle data.seattle.gov Building Permits

Everything is normalized into one schema.

Step 1: Configure the input

Open the Actor page and click Try for free. The defaults:

{
  "cities": [
    "chicago",
    "new-york",
    "los-angeles",
    "austin",
    "seattle"
  ],
  "daysBack": 7,
  "maxItemsPerCity": 20
}
Enter fullscreen mode Exit fullscreen mode

Useful options:

  • cities: any of chicago, new-york, los-angeles, austin, seattle.
  • daysBack or dateFrom / dateTo: the issue-date window.
  • keywords: match any word in the work description, for example ["ROOF", "SOLAR", "POOL"]. Matching isn't case-sensitive.
  • minValuation: a minimum reported job value. Permits without a value are excluded.
  • maxItemsPerCity: a per-city cap, newest first.

Step 2: Read the output

city permitNumber issueDate permitType address valuation
Chicago 101083682 2026-10-28 PERMIT - RENOVATION/ALTERATION 2620 W 51ST ST 15000
Chicago 101084071 2026-10-28 PERMIT - NEW CONSTRUCTION 1733 W JULIAN ST 475000
Chicago 101084225 2026-10-28 PERMIT - RENOVATION/ALTERATION 13122 S ELLIS AVE 14500000

Full records also include status, applied date, work type, description, ZIP, latitude and longitude, and contractor, owner or applicant details where the city publishes them.

Not every city publishes every field:

  • Contractor phone is only available for Austin.
  • Owner name is only available for Chicago and New York.
  • Los Angeles doesn't publish contractor names, and Chicago doesn't publish ZIP codes.
  • Valuation is whatever the applicant reported, and some cities use placeholders like 0 or 1.
  • Los Angeles usually runs three to five days behind.

Step 3: Schedule it

A one-off export is useful, but the real value is getting new records on a timetable without thinking about it.

  1. In Apify Console, open Schedules and click Create new.
  2. Set the cron expression. For example, 0 6 * * * runs it every morning at 6:00.
  3. Add the Actor (Building Permits Scraper) and paste the same input JSON you used above.
  4. Optional: under the Actor's Integrations tab, connect Google Sheets, Slack, Zapier, Make or a webhook so each finished run lands where your team already works.

For a trade-specific feed, save one schedule per trade, such as a roofing schedule with keywords: ["ROOF"] and a solar schedule with keywords: ["SOLAR"]. Use a daysBack of a few days so late-publishing cities are still covered, and de-duplicate on permitNumber.

Step 4: Run it from Python with apify-client

If you'd rather pull the data into your own scripts or CRM, use the official apify-client package (pip install apify-client). Grab your API token from Settings > API & Integrations in Apify Console and keep it in an environment variable rather than in code.

import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run_input = {
    "cities": [
        "austin",
        "seattle"
    ],
    "daysBack": 3,
    "keywords": [
        "ROOF",
        "SOLAR"
    ],
    "minValuation": 10000,
    "maxItemsPerCity": 50
}

run = client.actor("perskekits/building-permits-multi-city").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("city"), item.get("permitNumber"), item.get("permitType"), item.get("valuation"))
Enter fullscreen mode Exit fullscreen mode

Because each record has latitude and longitude, you can map the results or filter them to your service area before sending them to your sales team.

What it costs

The Actor uses Apify's pay-per-event pricing, so you pay for results, not for server time:

  • $0.005 per run start
  • $0.005 per permit returned

For example, 100 permits cost about $0.505, and 1,000 permits cost about $5.01. Apify's free plan includes a small amount of monthly platform credit, which is enough to try small runs. Check the Actor's pricing tab for the current rates before you run anything large.

FAQ

Which cities are supported?
Chicago, New York City, Los Angeles, Austin and Seattle. You can request more cities on the Actor's Issues tab.

Can I filter by trade or job size?
Yes. Use keywords for the trade and minValuation for job size.

Why are some fields empty?
Each city publishes a different set of fields. Anything a city doesn't publish comes back as null.

How current is the data?
Most portals update daily. Los Angeles usually lags three to five days.

Is it legal to use permits for marketing?
Permits are public records. You're responsible for following CAN-SPAM, TCPA, do-not-call and any local rules when you contact owners or contractors.

Wrapping up

Permits tell you who's about to spend money on a building project. Instead of stitching together five portals, get one clean feed every morning. Try the Building Permits Scraper on Apify.

Top comments (0)