# Building Permits Search: NYC, LA, Chicago, Seattle (`datapenguin/city-building-permits`) Actor

Search recently issued building permits in New York City, Los Angeles, Chicago and Seattle, all in one format. Filter by permit type, ZIP code, project cost and keyword, or get only permits you have not seen before. Official city open data, no API key.

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

## Pricing

from $3.00 / 1,000 permits

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

### Recently issued building permits in New York City, Los Angeles, Chicago and Seattle

Building Permits Search reads the permit files that four big cities publish as open data and gives you the newest ones in a single format. Each permit has the date issued, address, type of work, a plain description, estimated cost and, where the city publishes it, the contractor. You can narrow the list by permit category, ZIP code, project cost and keyword, or ask for only the permits you have not seen before.

There is no account, API key or login to set up. Pick your cities and start the run.

Contractors, suppliers, solar and roofing companies use permit lists to find jobs that have just been approved. Real estate investors and appraisers use them to see what is being built or torn down in a neighborhood, and local reporters use them to follow big projects.

#### How to use it

1. Click **Try for free** and open the **Input** tab.
2. Choose your cities, then add a category, a ZIP code or a keyword if you want a narrower list.
3. Click **Start**, then open the **Output** tab.

To get only fresh permits every day, turn on **Only permits not seen before** and run it on a schedule. The Actor remembers what it already gave you for that exact set of filters.

#### Example inputs

New buildings in Los Angeles, Chicago and Seattle over the last 30 days:

```json
{
    "cities": ["los-angeles", "chicago", "seattle"],
    "categories": ["new-building"],
    "daysBack": 30,
    "maxItems": 100
}
```

Roofing permits of $20,000 or more in all four cities:

```json
{
    "categories": ["roofing"],
    "minCostUsd": 20000,
    "daysBack": 14,
    "maxItems": 100
}
```

Anything that mentions solar in Manhattan, with a contractor named:

```json
{
    "cities": ["nyc"],
    "keywords": ["solar"],
    "zipCodes": ["100"],
    "onlyWithContractor": true,
    "maxItems": 50
}
```

#### What you get

For each permit: city, state, permit number, the city's own permit type, a simple category, status, work description, address, ZIP code, issue date, estimated cost in dollars, latitude and longitude. Where the city publishes them you also get the contractor name, license number and license type. Seattle permits include a link to the city's record.

Categories are new building, alteration or addition, general building work (New York only), demolition, roofing, electrical, plumbing and mechanical, signs, fences and scaffolds, and other.

A shortened example:

```json
{
    "city": "Chicago",
    "state": "IL",
    "permitNumber": "B200517451",
    "permitType": "EXPRESS PERMIT PROGRAM - Electrical Work",
    "category": "electrical",
    "status": "ACTIVE",
    "description": "LINE VOLTAGE ELECTRICAL WORK. ADD 1 CIRCUITS TO EXISTING 200 AMP SERVICE DISCONNECTING MEANS. RECEPTACLE OUTLETS: 1 . LIGHTING OUTLETS: 0.",
    "address": "9216 S PAXTON AVE",
    "issuedDate": "2026-10-26",
    "estimatedCostUsd": 1500,
    "contractorName": "NOLAN ELECTRIC CONSTR. CO. INC",
    "contractorLicenseType": "ELECTRICAL CONTRACTOR"
}
```

#### Which city publishes what

| City | Contractor name | License number | ZIP code | Dataset |
| --- | --- | --- | --- | --- |
| New York City | Yes | Yes | Yes | DOB NOW: Build, Approved Permits |
| Los Angeles | No | No | Yes | Building Permits Issued 2020 to Present |
| Chicago | Yes, when one is listed | No | No | Building Permits |
| Seattle | On some permits | No | Yes | Building Permits |

New York's file lists work by trade, such as plumbing or sprinklers, and does not say whether a job is a new building or an alteration. Those permits show up as general building work. New York business names are cut off at 25 characters in the city's file.

#### Pricing

You pay per use. There is no monthly fee.

| What | Price |
| --- | --- |
| Each permit returned | $0.003 |
| Starting a run | $0.00005 |

Getting 500 permits costs $1.50, which is $3 per 1,000. A search that finds nothing costs only the start fee. Set **Maximum cost per run** in the run options, or use **Max results**, to cap what a single run can spend.

#### Questions

##### Do I need an account or key with the cities?

No. The Actor uses each city's public data portal.

##### Where does the data come from, and how fresh is it?

New York City Department of Buildings, the City of Los Angeles, the City of Chicago and the City of Seattle, through their open-data portals. The files update every day, but they can trail the city's own permit system by a few days. In late October 2026 the newest Seattle permits were about four days old, so very short date windows can come back empty.

##### Why did I get fewer results than I asked for?

Usually the filters. A category, ZIP code or minimum cost narrows each city, and a city that does not publish a field cannot match a filter on it. Chicago is left out when you filter by ZIP code, and Los Angeles has no contractors, so it drops out when you ask for permits with a contractor.

##### Does a permit mean the work has happened?

No. A permit means the city approved the work. It may not have started, and some permits are never used.

##### Something is wrong or missing. Where do I report it?

Open a thread in the **Issues** tab with the input you used and the permit number. I answer within a few days.

#### Good to know

Owner names, phone numbers and mailing addresses are not included, because they are about private people and are not needed to find the work. The address is the address of the project.

This is an independent tool. It is not affiliated with, endorsed by or sponsored by any of the cities. Data can be incomplete or out of date, so confirm anything important with the city. This is not legal advice.

Chicago data: this site provides applications using data that has been modified for use from its original source, www.cityofchicago.org, the official website of the City of Chicago. The City of Chicago makes no claims as to the content, accuracy, timeliness, or completeness of any of the data provided at this site. The data provided at this site is subject to change at any time. It is understood that the data provided at this site is being used at one's own risk.

# Changelog

This Actor's version history is a separate document: https://apify.com/datapenguin/city-building-permits/changelog.md

# Actor input Schema

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

Which cities to search. Results are mixed evenly between the cities you pick. Leave empty for all four.

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

Only permits issued in this many days. City files run a few days behind, so very short windows can come back empty.

## `categories` (type: `array`):

Leave empty for every category. New York does not say whether work is new or an alteration, so its general construction permits are listed as General building work (NYC). Chicago and Los Angeles list electrical and plumbing permits in different ways, so check the permit type column too.

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

Match any of these words in the work description, permit type, contractor name or address, for example roof, solar or restaurant. Not case sensitive. Leave empty for no keyword filter.

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

Start of a ZIP code, for example 981 for part of Seattle or 100 for Manhattan. Chicago does not publish ZIP codes, so it is left out when you use this.

## `minCostUsd` (type: `integer`):

Only permits with an estimated cost at or above this amount, for example 100000. Permits with no cost listed are left out.

## `onlyWithContractor` (type: `boolean`):

Keep only permits that name a contractor. Los Angeles does not publish contractors, and Seattle names one on only some permits.

## `onlyNew` (type: `boolean`):

Skip permits that an earlier run with the same filters already delivered. Use this on a scheduled run to get just the new permits each time. Changing any filter starts a fresh list.

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

The most results to return. You are charged per result, so this also caps what a run can cost.

## Actor input object example

```json
{
  "cities": [
    "nyc",
    "los-angeles",
    "chicago",
    "seattle"
  ],
  "daysBack": 14,
  "categories": [
    "new-building",
    "alteration-addition",
    "building-work"
  ],
  "onlyWithContractor": false,
  "onlyNew": false,
  "maxItems": 25
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `summary` (type: `string`):

No description

# 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 = {
    "daysBack": 14,
    "categories": [
        "new-building",
        "alteration-addition",
        "building-work"
    ],
    "maxItems": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("datapenguin/city-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 = {
    "daysBack": 14,
    "categories": [
        "new-building",
        "alteration-addition",
        "building-work",
    ],
    "maxItems": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("datapenguin/city-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 '{
  "daysBack": 14,
  "categories": [
    "new-building",
    "alteration-addition",
    "building-work"
  ],
  "maxItems": 25
}' |
apify call datapenguin/city-building-permits --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datapenguin/city-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/rdCXl3Vn6EyogqOMm/builds/S94EFiCs9YCQOzBHb/openapi.json
