# US Building Permits API & Contractor Leads (`digital_influx/us-building-permits`) Actor

Building permits issued in New York City, Chicago, San Francisco, Seattle, Austin, Cincinnati and Baton Rouge: project value, work type, contractor (with phone in Austin), owner and address. Find solar, roofing, remodel and new construction jobs.

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

## Pricing

from $3.00 / 1,000 permit saveds

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 Permits API & Contractor Leads

**Building permits issued in seven US cities, in one clean format:** New York City, Chicago, San Francisco, Seattle, Cincinnati, Austin and Baton Rouge. Project value, work type, description, address, the contractor who pulled the permit (with phone in Austin), the owner where the city publishes it, and a link to the permit page. Find **solar, roofing, remodel, ADU, pool, HVAC and new construction** jobs the day they are permitted.

No login, no API key, no proxies: the data comes from the official open-data portals of each city, updated daily.

### Who uses it

- **Suppliers and distributors** (lumber, roofing, solar panels, HVAC equipment, windows, concrete): which contractors are starting which jobs, and how big they are.
- **Subcontractors and trades:** new construction and remodel permits to bid on, with the general contractor's name.
- **Home services and solar installers:** homes that just pulled a roofing, solar or remodel permit.
- **Real estate, lenders and analysts:** construction activity by ZIP code, new housing units, project values.

### What you get

One record per permit (New York City publishes one row per work type, San Francisco one per address, Cincinnati one per sub-permit; they are joined here).

| Field | Example |
|---|---|
| `source`, `jurisdiction` | `austin`, Austin, TX |
| `permitNumber`, `permitType`, `workClass` | 2026-129044 PP, Plumbing Permit, Commercial / Remodel |
| `workTypes` | Tags from the type and description: `new-construction`, `addition-remodel`, `roofing`, `solar`, `adu`, `pool`, `hvac`, `electrical`, `plumbing`, `demolition`, `signs` |
| `description`, `status` | CHANGE OF USE TO RESTAURANT with remodel, Active |
| `appliedDate`, `issuedDate` | 2026-06-03, 2026-10-01 |
| `projectValue` | The declared project cost in USD, where the city publishes it |
| `address`, `city`, `state`, `zip`, `latitude`, `longitude` | Where the work is |
| `housingUnits` | Units added or proposed (Seattle, San Francisco, Cincinnati, Austin) |
| `contractorName`, `contractorPhone`, `contractorLicense`, `contractorTrade` | RGV Plumbing, 9562225388 (Austin publishes phones) |
| `applicantName`, `ownerName` | Where the city publishes them |
| `contacts` | Chicago: every named contact with its role (owner, architect, general contractor, electrical, plumbing...) |
| `permitUrl`, `sourceUrl`, `retrievedAt` | The permit's page at the city (Seattle, Cincinnati, Austin), the dataset, and when it was read |
| `change` | With *Only new*: `new` or `updated` |

The run's **OUTPUT** record has the totals per city, the count per work type, the cities skipped by a filter and the attribution.

Example record (shortened):

```json
{
  "source": "austin",
  "permitNumber": "2026-129044 PP",
  "permitType": "Plumbing Permit",
  "workTypes": ["addition-remodel", "plumbing"],
  "description": "CHANGE OF USE TO RESTAURANT with remodel",
  "issuedDate": "2026-10-01",
  "address": "902 E 5TH ST UNIT 105",
  "zip": "78702",
  "contractorName": "RGV Plumbing",
  "contractorPhone": "9562225388",
  "permitUrl": "https://abc.austintexas.gov/web/permit/public-search-other?t_detail=1&t_selected_folderrsn=13781792"
}
```

### Input

Solar and roofing permits issued this week in New York City and Austin:

```json
{
  "sources": ["new-york-city", "austin"],
  "issuedWithinDays": 7,
  "workTypes": ["solar", "roofing"],
  "maxResults": 50
}
```

| Field | What it does |
|---|---|
| `sources` | `new-york-city`, `chicago`, `san-francisco`, `seattle`, `cincinnati`, `austin`, `baton-rouge`. Empty = all seven. |
| `issuedWithinDays` | The date window, 30 days by default. |
| `workTypes` | New construction, addition/remodel, roofing, solar, ADU, pool, HVAC, electrical, plumbing, demolition, signs. |
| `keywords` | Other words in the permit type or description, e.g. `kitchen`, `restaurant`, `elevator`, `EV charger`. |
| `minProjectValue` | Only permits with a declared cost of at least this many dollars. |
| `zipCodes` | 5-digit ZIP codes, or the first 3 digits for a wider area. |
| `onlyWithContractor` | Only permits that name a contractor. |
| `maxResults` | Newest first, across all cities (1,000 by default). |
| `onlyNew` + `memoryName` | For scheduled runs: only permits not saved before, or whose status, value or contractor changed. |
| `appToken` | Optional free Socrata app token, if a portal refuses requests. |

Projects worth a million dollars or more, all seven cities, last 30 days:

```json
{
  "minProjectValue": 1000000,
  "issuedWithinDays": 30
}
```

New construction and ADU permits in San Francisco and Seattle with a contractor:

```json
{
  "sources": ["san-francisco", "seattle"],
  "workTypes": ["new-construction", "adu"],
  "onlyWithContractor": true,
  "issuedWithinDays": 30
}
```

A daily feed of roofing permits in Austin ZIP codes 787xx (schedule it in *Schedules*):

```json
{
  "sources": ["austin"],
  "workTypes": ["roofing"],
  "zipCodes": ["787"],
  "onlyNew": true
}
```

### Only new or updated permits

Turn on **Only new** and schedule the task. Each run saves only the permits that earlier runs of the same search did not save, plus the ones whose status, value or contractor changed since. The memory lives in a key-value store named `us-building-permits-state` in your own Apify account and forgets permits issued before the date window. Give a **Memory name** to share it between tasks, or a new one to start over.

### Pricing

Pay per event: you pay **only for permits saved to the dataset**. Permits left out by your filters and permits already saved by an earlier run are free. Set a maximum cost for a run and the Actor stops cleanly when it is reached.

Measured on 2026-10-02: the last 7 days of all seven cities were 3,562 permits, read in about 13 seconds. In the last 30 days there were 687 solar permits, and 938 projects worth a million dollars or more.

### Use it from AI agents (MCP)

Claude, ChatGPT, Cursor and any other MCP client can run this Actor as a tool: add `https://mcp.apify.com?tools=digital_influx/us-building-permits` as a remote MCP server and sign in with your Apify account. It is also one of the tools of US & UK Public Records MCP (`digital_influx/public-records-mcp`), by the same author, made for agents.

### Good to know

- **What each city publishes differs.** Contractor names: New York City, Chicago, Cincinnati, Austin and Baton Rouge almost always, Seattle sometimes, San Francisco not in this dataset. Phones: Austin only. Owners: New York City, Chicago and Baton Rouge. Project values: most permits, except Austin trade permits.
- **Chicago does not publish the ZIP code of the work site**, so it is skipped when you filter by ZIP code (the OUTPUT says so). Its contacts list every named party.
- **Work types are found by words** in the permit type and description, so a few permits are tagged loosely (a sign permit for "signal" work, a roof mentioned in a scaffold permit).
- **Minimum value:** where the city stores the cost as a number (Chicago, Seattle, Austin, Baton Rouge) the portal filters it; elsewhere the Actor reads the window and filters it, which takes a little longer.
- **Requests:** one per second per portal, as their robots.txt asks. Without an app token the portals share a request limit per IP address; if a run reports a refused request, add a free Socrata app token.

### Sources and attribution

- New York City: NYC Department of Buildings (DOB), "DOB NOW: Build – Approved Permits", NYC Open Data, dataset rbx6-tga4. Each record carries the date it was read (`retrievedAt`); the Actor joins the rows of each permit issuance into one record, drops placeholder owner names ("PR", "Not Applicable") and renames the fields.
- Chicago: City of Chicago, "Building Permits", Chicago Data Portal, dataset ydr8-5enu. 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.
- San Francisco: Department of Building Inspection, "Building Permits", DataSF, dataset i98e-djp9 (Open Data Commons Public Domain Dedication and License).
- Seattle: City of Seattle, "Building Permits", dataset 76t5-zqzr (public domain).
- Cincinnati: City of Cincinnati, "Cincinnati Building Permits", dataset uhjb-xac9 (public domain).
- Austin: City of Austin, "Issued Construction Permits", dataset 3syk-w9eu (public domain).
- Baton Rouge: City of Baton Rouge and Parish of East Baton Rouge, "EBR Building Permits", dataset 7fq7-8j7r (public domain).

None of these cities endorses this Actor or any business in its results.

### Questions or ideas?

Want another city? Open an issue on the Issues tab: we answer within a few days.

# Actor input Schema

## `sources` (type: `array`):

Building departments to read. Empty = all seven.

## `issuedWithinDays` (type: `integer`):

Permits issued in the last N days. Most cities publish them within a day or two.

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

Keep permits whose type or description mentions one of these. Empty = every permit.

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

Other words to find in the permit type or description, e.g. kitchen, restaurant, elevator, EV charger.

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

Keep permits whose declared project cost is at least this much. Permits without a declared cost are left out when this is set.

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

5-digit ZIP codes, or their first 3 digits for a wider area (e.g. 787 for Austin). Chicago does not publish the ZIP code of the work site and is skipped.

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

Leave out permits pulled without a contractor's name (homeowner permits, or cities that do not publish it).

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

Newest permits first, across all cities. You also never pay more than the spending limit you set for the run.

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

Save only permits that earlier runs of this same search did not save, or whose status, value or contractor changed since (each row says which). Schedule it daily or weekly. The memory lives in a key-value store named "us-building-permits-state" in your account.

## `memoryName` (type: `string`):

By default each search has its own memory. Give a name to share one memory between tasks, or a new name to start over.

## `appToken` (type: `string`):

Without a token, the portals share a request limit per IP address. A free app token from any Socrata portal gives you your own limit. Only needed if a run reports a refused request.

## Actor input object example

```json
{
  "sources": [
    "new-york-city",
    "austin"
  ],
  "issuedWithinDays": 7,
  "workTypes": [
    "solar",
    "roofing"
  ],
  "onlyWithContractor": false,
  "maxResults": 50,
  "onlyNew": false
}
```

# Actor output Schema

## `results` (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 = {
    "sources": [
        "new-york-city",
        "austin"
    ],
    "issuedWithinDays": 7,
    "workTypes": [
        "solar",
        "roofing"
    ],
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("digital_influx/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 = {
    "sources": [
        "new-york-city",
        "austin",
    ],
    "issuedWithinDays": 7,
    "workTypes": [
        "solar",
        "roofing",
    ],
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("digital_influx/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 '{
  "sources": [
    "new-york-city",
    "austin"
  ],
  "issuedWithinDays": 7,
  "workTypes": [
    "solar",
    "roofing"
  ],
  "maxResults": 50
}' |
apify call digital_influx/us-building-permits --silent --output-dataset

```

## MCP server setup

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