# US Building Permit Leads: Chicago, LA, Austin, Seattle (`flecked_coffee/us-permit-leads`) Actor

New building, electrical, HVAC and plumbing permits from Chicago, Los Angeles, Austin, Seattle and Charlotte in one schema, from each city's official open-data feed. Flags projects that don't have an electrical, HVAC or plumbing permit yet, so trade contractors see open jobs first.

- **URL**: https://apify.com/flecked_coffee/us-permit-leads.md
- **Developed by:** [Jordon Penninger](https://apify.com/flecked_coffee) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 permit results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## US Building Permit Leads: Chicago, Los Angeles, Austin, Seattle, Charlotte

New building, electrical, HVAC and plumbing permits from **five US cities in one Actor and one schema**. The data comes straight from each city's official open-data feed. Pick a city, set your filters, and get a lead list you can send to Google Sheets, a CRM or email.

| City | Source | Typical volume | Trades checked |
|---|---|---|---|
| Chicago, IL | City of Chicago Building Permits | ~2,500 permits / month | Electrical, Mechanical, Plumbing |
| Los Angeles, CA | LADBS building, electrical and mechanical permits | ~15,000 / month | Electrical, Mechanical, Plumbing |
| Austin, TX | Austin Development Services issued permits | ~5,000 / month | Electrical, Mechanical, Plumbing |
| Seattle, WA | SDCI building, electrical and trade permits | ~4,500 / month | Electrical, Mechanical |
| Charlotte, NC | Mecklenburg County Accela permits | ~11,000 / month | Electrical, Mechanical, Plumbing |

### What makes it different: open-trade leads

Most permit scrapers copy one city's table and stop there. This Actor reads every city's **trade permits** as well and matches them to each project by address and parcel. For every project permit (new building, addition, remodel, tenant improvement, pool…) you get:

- `tradePermitsOnFile`: the trades that already have a permit (or, in Chicago, a licensed contractor listed on the permit)
- `tradesNotYetPermitted`: the trades that **don't have one yet**

Set **Only projects still missing this trade** to `Electrical`, `Mechanical` or `Plumbing` to get just the jobs where that sub may still be open. On a typical week that's about 20% of Chicago projects and most new projects in Austin, Seattle and Los Angeles.

One input, one output format, five cities. Switch the city, keep your Zap, Make scenario or spreadsheet.

### Who uses it

- **Electricians, HVAC and plumbing contractors** finding projects before the trade work is awarded
- **Solar, EV-charger, generator and low-voltage installers**: `evCharger` and `solar` flags, plus keyword filters
- **Suppliers and distributors** tracking new construction by ZIP code or neighborhood
- **Lenders, investors and market researchers** comparing construction activity across cities

### Input

| Field | What it does |
|---|---|
| City | Chicago, Los Angeles, Austin, Seattle or Charlotte (required) |
| Days back / Start date / End date | Issue-date range. Default: the last 7 days the city has published. |
| Only projects still missing this trade | `Electrical`, `Mechanical` or `Plumbing` |
| Work types | Every city uses `New`, `Electrical`, `Mechanical`, `Plumbing`; plus city types like `Renovation/Alteration` (Chicago), `Pool/Spa` (LA), `Remodel` (Austin), `Tenant Improvement` (Seattle) |
| Residential or commercial | Both, Residential or Commercial |
| Towns or neighborhoods | Chicago community areas (`Logan Square`), LA plan areas (`Hollywood`), Austin-area towns, Charlotte-area towns |
| ZIP codes | Limit the area (Chicago's feed has no ZIPs; use neighborhoods) |
| Minimum project value | Declared construction cost |
| Keywords | Match the description or building use (e.g. `ADU`, `generator`, `restaurant`) |
| Max results | Cap the number of results (and the cost) |

### Output

One item per permit, the same fields for every city:

```json
{
  "city": "Austin, TX",
  "permitNumber": "2026-050095 BP",
  "issueDate": "2026-10-26",
  "status": "Active",
  "workType": "Addition and Remodel",
  "category": "Commercial",
  "description": "Addition and Remodel to Existing Admin Office Building to Create Visitors Center and Office (42552 SF).",
  "projectValue": 1000000,
  "address": "11920 WILSON PARKE AVE",
  "zipCode": "78726",
  "jurisdiction": "Austin",
  "latitude": 30.4228954,
  "longitude": -97.85178342,
  "mapUrl": "https://www.google.com/maps/search/?api=1&query=30.4228954,-97.85178342",
  "isProjectPermit": true,
  "tradePermitsOnFile": [],
  "tradesNotYetPermitted": ["Electrical", "Mechanical", "Plumbing"],
  "tradesChecked": ["Electrical", "Mechanical", "Plumbing"],
  "contractorCompany": "Spawglass Contractors Inc",
  "evCharger": false,
  "solar": false,
  "lookupUrl": "https://abc.austintexas.gov/web/permit/public-search-other?t_detail=1&t_selected_folderrsn=13691852"
}
```

Also included where the city publishes them: neighborhood, parcel ID, square feet, housing units and building use. `lookupUrl` opens the permit on the city's own site (Austin, Seattle and Los Angeles link to the exact permit). Download as JSON, CSV or Excel, or connect it to Google Sheets, Zapier or Make.

### Tips

- **Daily lead list:** schedule one run per city each morning with `Days back = 2` and send the dataset to Google Sheets or email.
- **Los Angeles posts weekly**, so its newest permits are usually 1 to 8 days old. "Days back" counts from the newest day each city has published, so a 7-day run always returns a full week.
- "No electrical permit yet" means none has been issued at that address or parcel since a month before the project permit. The builder may already have a sub who hasn't pulled it, and in Los Angeles trade permits are often pulled late in the job. Treat it as a lead, not a guarantee.
- Seattle's plumbing permits are issued by King County public health, not the city, so Seattle checks electrical and mechanical only (`tradesChecked` says which trades were checked for every result).

### Data and privacy

Public permit records published by each city or county. Owner, applicant and contact names, phone numbers and email addresses are **not** collected. Contractor company names are included for Chicago and Austin only when they are clearly a business. This Actor is not affiliated with any of these cities or counties.

# Actor input Schema

## `city` (type: `string`):

Which city's permits to return. Each run reads one city; schedule one run per city to cover several.

## `daysBack` (type: `integer`):

How many days of issued permits to return, ending on the newest day the city has published (usually yesterday; Los Angeles publishes once a week). Ignored if you set a start date.

## `startDate` (type: `string`):

Optional. First issue date to include (YYYY-MM-DD).

## `endDate` (type: `string`):

Optional. Last issue date to include (YYYY-MM-DD). Defaults to the newest day the city has published.

## `onlyProjectsMissingTrade` (type: `string`):

Return only project permits (new buildings, additions, remodels, tenant improvements, pools...) with no permit or listed contractor for this trade yet. Seattle's feeds cover electrical and mechanical only, so the plumbing option returns nothing there.

## `workTypes` (type: `array`):

Leave empty for all. Every city uses New, Electrical, Mechanical and Plumbing. Others by city: Chicago Renovation/Alteration, Express Permit Program, Wrecking/Demolition, Signs; Los Angeles Addition, Alteration/Repair, Pool/Spa, Demolition, Fire Sprinkler; Austin Remodel, Addition and Remodel, Shell, Repair, Demolition; Seattle Addition/Alteration, Tenant Improvement, Demolition, Roof; Charlotte Addition, Alteration, Upfit, PoolSpa, SolarPV.

## `category` (type: `string`):

Keep only residential or commercial permits, or both. Chicago doesn't publish this, so leave it on Both for Chicago.

## `jurisdictions` (type: `array`):

Leave empty for the whole city. Chicago: community areas such as Lincoln Park, Logan Square, Near West Side. Los Angeles: community plan areas such as Venice, Hollywood, Brentwood - Pacific Palisades. Austin: Austin, Buda, Bee Cave, Lakeway, Del Valle. Charlotte: Charlotte, Huntersville, Cornelius, Davidson, Matthews, Mint Hill, Pineville.

## `zipCodes` (type: `array`):

Leave empty for all ZIP codes. Chicago's feed has no ZIP codes, so use neighborhoods there.

## `minProjectValue` (type: `integer`):

Skip permits with a declared construction cost below this. Many trade permits have no value and are skipped when this is set.

## `keywords` (type: `array`):

Keep permits whose description or building use contains any of these words, e.g. generator, EV charger, panel, ADU, restaurant.

## `includeClosed` (type: `boolean`):

Also return permits the city marked cancelled, withdrawn, void, revoked or expired.

## `maxItems` (type: `integer`):

Stop after this many permits. 0 means no limit.

## Actor input object example

```json
{
  "city": "chicago",
  "daysBack": 7,
  "onlyProjectsMissingTrade": "none",
  "workTypes": [
    "New"
  ],
  "category": "any",
  "includeClosed": false,
  "maxItems": 0
}
```

# Actor output Schema

## `permits` (type: `string`):

One item per permit: city, issue date, permit number, work type, value, address and which trades are not permitted yet.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "workTypes": [
        "New"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("flecked_coffee/us-permit-leads").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "workTypes": ["New"] }

# Run the Actor and wait for it to finish
run = client.actor("flecked_coffee/us-permit-leads").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "workTypes": [
    "New"
  ]
}' |
apify call flecked_coffee/us-permit-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,flecked_coffee/us-permit-leads"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/rlzj9PgsnAK6yTIKS/builds/yHKfCe4PTqlcd0TlI/openapi.json
