# US Building Permits Scraper: Construction Permit Data (`lepidata/us-building-permits`) Actor

Building and construction permits from public US city open-data portals, mapped to one format: permit number, type, status, dates, address, valuation and contractor business name. No owner or contractor contacts.

- **URL**: https://apify.com/lepidata/us-building-permits.md
- **Developed by:** [Lepi Data](https://apify.com/lepidata) (community)
- **Categories:** Real estate, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 building permits

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Permits Scraper

*Unofficial tool. Not affiliated with, endorsed by, or sponsored by any city, county, or government agency.*

Pull recent building and construction permits from public city open-data portals and get them back in one shared format, whichever city they came from. It's for contractors, suppliers, solar, roofing and HVAC sales teams, real-estate analysts and researchers tracking construction activity.

**Cities covered:** San Francisco, CA · Seattle, WA · Austin, TX · Cincinnati, OH · Baton Rouge / East Baton Rouge Parish, LA.

**Input:** city, issue-date range, and optional permit type, status and minimum valuation filters, plus a maximum number of results.

**Output:** city, permit number, permit type and work class, work description, status, application, issue and completion dates, site address and ZIP, valuation, housing units, contractor business name, coordinates and a source link.

No owner or applicant name, phone or email fields are returned. Work descriptions are filtered to remove person names, phone numbers and emails, and anything that slips through can be reported through the removal-request line below. No contractor contact details either: no contractor phone, email or street address, only the business name. Each city's data license and attribution are listed below.

### Construction permit data sources, licenses and attribution

| City | Dataset | License (as shown on the dataset page) | Attribution |
|---|---|---|---|
| San Francisco, CA | [Building Permits (i98e-djp9)](https://data.sf.gov/Housing-and-Buildings/Building-Permits/i98e-djp9) | [Open Data Commons Public Domain Dedication and License](http://opendatacommons.org/licenses/pddl/1.0/) | Source: DataSF. City and County of San Francisco, Department of Building Inspection (data.sf.gov). |
| Seattle, WA | [Building Permits (76t5-zqzr)](https://data.seattle.gov/Built-Environment/Building-Permits/76t5-zqzr) | Public Domain | Source: City of Seattle (data.seattle.gov). |
| Austin, TX | [Issued Construction Permits (3syk-w9eu)](https://data.austintexas.gov/Building-and-Development/Issued-Construction-Permits/3syk-w9eu) | [Public Domain U.S. Government](https://www.usa.gov/government-works) | Source: City of Austin, Texas - data.austintexas.gov. |
| Cincinnati, OH | [Cincinnati Building Permits (uhjb-xac9)](https://data.cincinnati-oh.gov/thriving-neighborhoods/Cincinnati-Building-Permits/uhjb-xac9) | Public Domain | Source: City of Cincinnati (data.cincinnati-oh.gov). |
| Baton Rouge / East Baton Rouge Parish, LA | [EBR Building Permits (7fq7-8j7r)](https://data.brla.gov/Housing-and-Development/EBR-Building-Permits/7fq7-8j7r) | Public Domain | Source: City of Baton Rouge / Parish of East Baton Rouge, Permits and Inspections (data.brla.gov). |

Every row also carries `sourceLicense`, `sourceLicenseUrl`, `sourceAttribution` and `datasetUrl`. No city seals or logos are used, and no city has endorsed this tool.

### Building permits input

- `cities`: any of `san-francisco`, `seattle`, `austin`, `cincinnati`, `baton-rouge` (empty = all five). `maxResults` is split evenly across them.
- `issuedFrom` / `issuedTo`: YYYY-MM-DD (default: the last 30 days)
- `lastNDays`: optional, permits issued in the last N days, counted back from today's UTC date when the run starts. Overrides `issuedFrom` / `issuedTo`, so a saved task never goes stale.
- `permitTypes`: words matched against permit type and work class only, e.g. `new`, `roof`, `demolition`, `electrical`, `residential`
- `statuses`: the city's own status values, e.g. `issued` (SF, Seattle, Cincinnati), `Active` / `Final` (Austin). Baton Rouge publishes no status and is skipped (free `filter-unsupported` row).
- `minValuation`: minimum stated project value in USD
- `maxResults`: up to 20,000

There is no free-text or name search: you can't search by contractor, owner or applicant name.

### Permit data output fields

`city`, `cityKey`, `permitNumber`, `permitType`, `workClass`, `description`, `status`, `appliedDate`, `issuedDate`, `completedDate`, `siteAddress`, `zip`, `valuation`, `housingUnits`, `contractorBusinessName`, `contractorTrade` (Austin only), `latitude`, `longitude`, `permitUrl` (Seattle, Austin, Cincinnati), `datasetUrl`, `sourceLicense`, `sourceLicenseUrl`, `sourceAttribution`

City notes: San Francisco publishes no contractor name, so `contractorBusinessName` is empty there. In Baton Rouge, a person's name the city appends after the business name is removed. **Baton Rouge ships no project description** (`description` is always `null` there), for privacy: the city's free-text notes can contain owners' names. Fields a city doesn't publish are `null`.

Free status rows (not charged): `no-results`, `invalid-input`, `api-error`, `filter-unsupported`, `free-plan-limit`, `charge-limit-reached`.

**Example:** `{"cities":["seattle","austin"],"issuedFrom":"2026-10-01","permitTypes":["new"],"minValuation":100000,"maxResults":20}`

### Ready-made examples

- [New Construction Permits Over $1M, 5 Cities](https://apify.com/lepidata/us-building-permits/examples/new-construction-permits-over-1m): newly issued new-construction permits with a stated project value of $1M or more across the five supported cities, last 30 days.
- [Roofing Permits in Seattle, Latest](https://apify.com/lepidata/us-building-permits/examples/seattle-roofing-permits): recently issued roofing permits in Seattle, last 30 days, newest first.

Unofficial examples. Not affiliated with or endorsed by any company or agency named above.

### Privacy, limits and compliance

- Only explicitly listed fields are requested from each portal and returned. Owner, applicant and contact columns are never downloaded.
- Email addresses and phone numbers in work descriptions are replaced with `[email removed]` / `[number removed]`.
- Person-name patterns in work descriptions (e.g. `Name (Owner)`, `Owner: Name`, `Mr./Ms. Name`, `Name called in`) are replaced with `[redacted]`. Baton Rouge descriptions are not output at all.
- A contractor business name can sometimes be a sole proprietor's own trading name, as published by the city.
- **Removal requests:** email theuser@mail.grokbot.com with the city and permit number, and we will remove or suppress the record in this Actor's output.
- Data comes from each city's public Socrata open-data API, paced at about 3 requests a second with a contact User-Agent. No API key.
- Data is as published by each city and can be incomplete or late. Check the city's record before relying on it.
- Free-plan accounts get up to 100 results per run.

**Pricing.** Pay per result: $1.80 per 1,000 permits ($0.0018 each), the same price on every plan, no start fee. Free status rows are never charged.

# Actor input Schema

## `cities` (type: `array`):

Leave empty for all five cities. Max results are split evenly across the cities you pick.

## `issuedFrom` (type: `string`):

YYYY-MM-DD. Default: 30 days ago.

## `issuedTo` (type: `string`):

YYYY-MM-DD. Default: today.

## `lastNDays` (type: `integer`):

Optional. Permits issued on or after today minus N days (UTC date, worked out when the run starts). Overrides Issued from / Issued to. Leave empty to use the fixed dates.

## `permitTypes` (type: `array`):

Words matched against the permit type and work class only, e.g. new, building, roof, demolition, electrical, plumbing, HVAC, residential, commercial. Not a name search.

## `statuses` (type: `array`):

Exact status values (case-insensitive), e.g. issued, complete (SF), Issued, Completed (Seattle), Active, Final (Austin), ISSUED, CLOSED (Cincinnati). Baton Rouge has no status, so it is skipped when this is set.

## `minValuation` (type: `integer`):

Only permits with a stated project value of at least this amount.

## `maxResults` (type: `integer`):

Total across all selected cities, up to 20,000.

## Actor input object example

```json
{
  "cities": [
    "seattle"
  ],
  "maxResults": 10
}
```

# Actor output Schema

## `items` (type: `string`):

All rows from this run.

# 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 = {
    "cities": [
        "seattle"
    ],
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("lepidata/us-building-permits").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 = {
    "cities": ["seattle"],
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("lepidata/us-building-permits").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 '{
  "cities": [
    "seattle"
  ],
  "maxResults": 10
}' |
apify call lepidata/us-building-permits --silent --output-dataset

```

## MCP server setup

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

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/t19ObcI1egLLdPiKj/builds/aPR61mjXFxhf2ejob/openapi.json
