# US Commercial Building Permit Leads — CHI, ATX, LA (`afkdigital/newapi07-us-commercial-building-permits`) Actor

Commercial building permit signals from official Chicago, Austin and Los Angeles open data. Filter issue dates, reported valuation and permit/work types; export JSON or CSV. Not actual spend, a completed project, or verified contractor identities.

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

## Pricing

$5.00 / 1,000 unique commercial 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.

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 Multi-City Commercial Building Permit Leads (NEWAPI07)

Turn **official city building permit records** into structured, deduplicated commercial project signals. Choose a single city, issue-date window, reported valuation floor, permit/work type filters, result cap, and dollar cap. Export to **JSON or CSV** in Apify's Dataset UI/API.

This Actor does **not** claim construction completion, actual project expenditure, contract awards, or verified contractor identity. **Reported valuation** means the municipality's published figure, not realized spend. Some records have no disclosed valuation or contractor; missing data is returned as JSON null.

### Supported sources and city-specific mapping

| City | Official data | Permit ID | Issued date | Reported amount | Commercial determination | Named party |
|---|---|---|---|---|---|---|
| **CHI** Chicago | [Chicago Building Permits](https://data.cityofchicago.org/d/ydr8-5enu) | permit\_ | issue_date | reported_cost | Conservative positive business/non-residential signal in work_description; **not comprehensive** | Contact with source type contractor or applicant; otherwise null |
| **ATX** Austin | [Issued Construction Permits](https://data.austintexas.gov/d/3syk-w9eu) | permit_number | issue_date | total_job_valuation | City's permit_class_mapped = Commercial | contractor_company_name where provided, else applicant organization/name or null |
| **LA** Los Angeles | [Building and Safety - Building Permits Issued 2020–Present](https://data.lacity.org/d/pi9x-tg5x) | permit_nbr | issue_date | valuation (source text, parsed to number) | City's permit_sub_type = Commercial | **null: dataset does not publish contractor/applicant name** |

**Chicago precision trade-off:** the public dataset has no explicit residential/commercial classification. Only descriptions with positively classifiable business terms or a positive non-residential unit count are emitted, and residential-only/zero-nonresidential records are rejected. Some real commercial permits will be missed; do not interpret a missing permit as proof of no activity.

**Date ranges:** issue_date is not an application date or the date work finished. Chicago's published date may represent the readiness-to-issue milestone for some permit types rather than fee-paid issuance; consult the official source notes.

**Source freshness:** Austin reports daily changes; Los Angeles usually weekly, Chicago is frequently refreshed. The Actor validates expected source columns every run; city records are subject to corrections.

**Attribution and terms:** source URLs are retained in each row. Austin dataset indicates U.S. Government Public Domain and carries a disclaimer. Chicago marks its license "See Terms of Use"; consult its [data portal](https://data.cityofchicago.org/). Los Angeles [Open Data Terms of Use](https://data.lacity.org/terms-of-use) apply; public city data are informational and subject to change. This independent product is not affiliated with or endorsed by any city.

### Input

| Field | Meaning |
|---|---|
| city | ATX (default), CHI, LA |
| startDate | optional inclusive issue date YYYY-MM-DD, default 30 days before end |
| endDate | optional inclusive issue date, default current UTC day |
| minReportedCost | minimum city-published valuation, default 10000 USD |
| permitType | case-insensitive substring of city permit type |
| workType | case-insensitive substring of city work class/category/description |
| maxResults | distinct (city, permit_id) cap, default 50 |
| maxCostUsd | result-event dollar ceiling, default 0.25 USD |

Example JSON input:

```
{"city":"ATX","startDate":"2026-10-01","endDate":"2026-10-16",
 "minReportedCost":50000,"maxResults":50,"maxCostUsd":0.25}
```

### Output

permit_id, city, permit_type, work_description, reported_cost, cost_currency, applicant_contractor_name, property_address, issue_date, source_dataset, source_record_url, observed_at.

Each row has official source links. Missing source fields are null; no generated or inferred company names.

### Pricing

**Target: USD $0.005 per unique permit result**, via Apify Pay Per Event custom event permit-record (1000 unique records = $5.00 in result events). No premium proxy needed. The input dollar cap also limits results to floor(maxCostUsd / 0.005); Apify's built-in **Max total charge** is the authoritative spending limit. An Apify synthetic startup event, if configured, may add its own fee; check the Store Pricing panel.

This price becomes active only when the publisher configures Pay Per Event and the corresponding event rate in Apify Publishing. Production fails closed if the Actor is not monetized; a developer test override exists strictly for controlled private tests.

### Technical implementation

- Socrata SODA JSON and SoQL, **server-side date, valuation and commercial filters**, stable (issue_date, source_row_id) keyset pagination, timeouts and capped 429/transient-5xx backoff.
- City schema drift validation, per-run output reconciliation, checkpoint after each emitted record, deduplication by (city, permit_id) on resume.
- Fixed source hosts and dataset IDs; user-provided strings are escaped, never injected as SoQL code.
- 240-second processing budget, 150-page safety cap, up to 10000 results per run.
- Absent or unparseable valuation is null when no minimum is applied; otherwise omitted.
- CSV is standard Dataset API format=csv; JSON is format=json. No extra bill for format conversion.

### Responsible use

Public permits are **signals, not opted-in sales leads**. Respect privacy and marketing law; do not assume contractors are verified or construction completed.

### Development

Python 3.12+. Install requirements.txt then run python -m unittest discover -s tests -v. Use Apify CLI to deploy. ACTOR_TEST_PAY_PER_EVENT=true can simulate billing locally (it does not charge real users).

# Actor input Schema

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

Choose one verified city dataset per run.

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

Inclusive YYYY-MM-DD; omitted = 30 days before end date.

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

Inclusive YYYY-MM-DD; omitted = current UTC date.

## `minReportedCost` (type: `number`):

Reported valuation is not actual spending; city records may omit it.

## `permitType` (type: `string`):

Case-insensitive substring of the city's permit type.

## `workType` (type: `string`):

Case-insensitive substring of the city's work class/category.

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

Hard output cap, also constrained by maxCostUsd.

## `maxCostUsd` (type: `number`):

Local result charge cap at USD 0.005 per distinct permit; Apify run-level spending limit also applies.

## Actor input object example

```json
{
  "city": "ATX",
  "minReportedCost": 10000,
  "permitType": "",
  "workType": "",
  "maxResults": 50,
  "maxCostUsd": 0.25
}
```

# Actor output Schema

## `results` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("afkdigital/newapi07-us-commercial-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("afkdigital/newapi07-us-commercial-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 '{}' |
apify call afkdigital/newapi07-us-commercial-building-permits --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,afkdigital/newapi07-us-commercial-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/lRrX9vxxn0VsY6SAn/builds/ybpfnOOJi7qdFKE2t/openapi.json
