Chicago Building Permits Scraper (Contractors, Owners)
Pricing
from $9.23 / 1,000 results
Chicago Building Permits Scraper (Contractors, Owners)
Scrape City of Chicago building permits for construction leads. Extract address, permit type, work description, issue dates, reported cost, total fees, and owner and contractor contacts. Export to JSON, CSV or Excel.
Pricing
from $9.23 / 1,000 results
Rating
5.0
(1)
Developer
Scrapers Lat
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
20 hours ago
Last modified
Categories
Share
Chicago Building Permits Scraper (Contractors, Owners)
Here is one real result, with every field the actor returns:
{"permitNumber": "B200506822","permitId": "N2960310","permitType": "PERMIT – EXPRESS PERMIT PROGRAM","reviewType": "EXPRESS PERMIT PROGRAM","permitStatus": "ACTIVE","permitMilestone": "INSPECTIONS","workType": "Electrical Work","workDescription": "LINE VOLTAGE ELECTRICAL WORK. NEW PERMANENT 100 AMP SERVICE DISCONNECTING MEANS WITH 1 CIRCUITS. RECEPTACLE OUTLETS: 1 . LIGHTING OUTLETS: 0. SPECIFIC LOCATION: FRONT.","permitConditions": null,"address": "1746 N STOCKTON DR, CHICAGO, IL","streetNumber": "1746","streetDirection": "N","streetName": "STOCKTON DR","applicationDate": "2026-08-10","issueDate": "2026-08-12","processingDays": 2,"reportedCost": 1000,"totalFee": 100,"feesPaid": 100,"feesUnpaid": 0,"feesWaived": 0,"feeBreakdown": {"building": {"subtotal": 75, "paid": 75, "unpaid": 0, "waived": 0},"zoning": {"subtotal": 0, "paid": 0, "unpaid": 0, "waived": 0},"other": {"subtotal": 25, "paid": 25, "unpaid": 0, "waived": 0}},"ownerName": "CHICAGO SPECIAL EVENTS MANAGEMENT","ownerCity": "CHICAGO","ownerState": "IL","contractorName": "HAUGER ELECTRIC","contractorType": "ELECTRICAL CONTRACTOR","contractorCity": "GLENDALE HEIGHTS","contractorState": "IL","contacts": [{"type": "OWNER", "name": "CHICAGO SPECIAL EVENTS MANAGEMENT", "city": "CHICAGO", "state": "IL", "zip": "60609"},{"type": "WEB APPLICANT", "name": "HAUGER KEN", "city": "CHICAGO", "state": "IL", "zip": "60139"},{"type": "ELECTRICAL CONTRACTOR", "name": "HAUGER ELECTRIC", "city": "GLENDALE HEIGHTS", "state": "IL", "zip": "60139"}],"ward": "43","communityArea": "7","censusTract": "71500","pinList": "1433210003","latitude": "41.9144421056552","longitude": "-87.6322626481453","aiSummary": "This permit authorizes electrical work at 1746 N Stockton Dr, Chicago, IL, involving the installation of a new permanent 100 AMP service disconnecting means with one circuit. The work is being performed by Hauger Electric and has a reported cost of $1,000.","aiExtract": {"scope": "LINE VOLTAGE ELECTRICAL WORK","structureType": null,"unitCount": null,"storyCount": null,"isNewConstruction": true,"materials": ["100 AMP SERVICE DISCONNECTING MEANS", "RECEPTACLE OUTLETS"],"trades": ["Electrical Work"]},"observedAt": "2026-08-14T07:22:30.607Z","error": null}
The most complete Chicago building permits scraper available. It returns every field the City of Chicago permit dataset exposes for each permit, including owner and contractor names with city and state, a full contacts list, fee breakdown, ward, community area and coordinates, plus optional AI summaries and structured work-detail extraction, and gives you free-text search plus a dozen filters to target exactly the permits and leads you need.
📥 Input · 📤 Output · 💰 Pricing · ▶️ Examples
Table of contents
- What it does
- Quickstart
- Input reference
- Output reference
- Example output record
- Run via API and CLI
- Fetch results
- Billing and limits
- FAQ and troubleshooting
What it does
The actor queries the City of Chicago building permits open dataset, applies the filters you pass as input, and writes one normalized record per permit to the run's dataset, newest issued first. Each record carries the permit number and ID, type, status and milestone, work type and description, full address with parsed street parts, application and issue dates with processing days, reported cost, fees with a paid/unpaid/waived breakdown, owner and contractor names with city and state, a full contacts list, ward, community area, census tract, PINs, and coordinates. Missing source values are returned as null.
Optional AI add-ons (paid Apify plans only) add a plain-English permit summary and a structured extraction of the work (scope, structure type, unit and story counts, new-construction flag, materials, trades).
Quickstart
Open the actor, paste this into the input, and press Run. It returns the 5 most recently issued Chicago permits with AI summary and extraction enabled.
{"maxPermits": 5,"withAiSummary": true,"withAiExtract": true}
Every filter is optional. With an empty input the actor returns the most recently issued permits (default maxPermits is 10).
Input reference
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
maxPermits | integer | no | 10 | Maximum number of permit records to collect. Newest issued first. |
query | string | no | (empty) | Free-text search across the whole permit record, including work description and every owner and contractor name, for example ROOF, ADDITION, or a company name. |
permitType | enum | no | (any) | Restrict to one permit type (Express Permit, Easy Permit, Renovation/Alteration, New Construction, Signs, Elevator, Wrecking/Demolition, Scaffolding, Porch, Reinstate Revoked, Extension). |
workType | string | no | (empty) | Match the work type, for example ELECTRIC, PLUMBING, ROOF. Case-insensitive, matches anywhere. |
minCost | integer | no | (none) | Only permits with a reported construction cost of at least this many US dollars. |
issuedFrom | string | no | (empty) | Only permits issued on or after this date (YYYY-MM-DD). |
issuedTo | string | no | (empty) | Only permits issued on or before this date (YYYY-MM-DD). |
ward | string | no | (empty) | Restrict to a single Chicago ward number, for example 43. |
communityArea | string | no | (empty) | Restrict to a single community area number (1 to 77), for example 6. |
street | string | no | (empty) | Match permits on a street name, for example HALSTED. Do not include direction or number. |
ownerName | string | no | (empty) | Match the property owner name (person or company). |
contractorName | string | no | (empty) | Match any contractor company on the permit. |
appToken | string | no | (empty) | Optional Socrata app token that raises the rate limit for very large pulls. |
withAiSummary | boolean | no | false | Paid add-on. Summarize each permit's work description in plain English. Requires a paid plan and a work description. Billed only when a summary is produced. |
withAiExtract | boolean | no | false | Paid add-on. Extract structured work details from the description. Requires a paid plan and a work description. Billed only when details are produced. |
Filters combine with logical AND.
Output reference
One dataset item per permit. Types: string, integer, object[], object, or null when the source value is absent.
| Field | Type | Description |
|---|---|---|
permitNumber | string | Chicago permit number. |
permitId | string | Internal permit ID. |
permitType | string | Permit type. |
reviewType | string | Review / program type. |
permitStatus | string | Permit status, for example ACTIVE. |
permitMilestone | string | Current permit milestone. |
workType | string | Work type, for example Electrical Work. |
workDescription | string | Full narrative work description. |
permitConditions | string | Permit conditions text, or null. |
address | string | Full permit address. |
streetNumber | string | Parsed street number. |
streetDirection | string | Parsed street direction. |
streetName | string | Parsed street name. |
applicationDate | string | Application date (YYYY-MM-DD). |
issueDate | string | Issue date (YYYY-MM-DD). |
processingDays | integer | Days between application and issue. |
reportedCost | integer | Reported construction cost in US dollars. |
totalFee | integer | Total permit fee. |
feesPaid | integer | Fees paid. |
feesUnpaid | integer | Fees unpaid. |
feesWaived | integer | Fees waived. |
feeBreakdown | object | Fee subtotals by category (building, zoning, other) with paid/unpaid/waived. |
ownerName | string | Property owner name. |
ownerCity | string | Owner city. |
ownerState | string | Owner state. |
contractorName | string | Primary contractor company. |
contractorType | string | Contractor type, for example ELECTRICAL CONTRACTOR. |
contractorCity | string | Contractor city. |
contractorState | string | Contractor state. |
contacts | object[] | All permit contacts (type, name, city, state, zip). |
ward | string | Chicago ward number. |
communityArea | string | Community area number. |
censusTract | string | Census tract. |
pinList | string | Parcel identification numbers. |
latitude | string | Latitude of the permit location. |
longitude | string | Longitude of the permit location. |
aiSummary | string | AI permit summary (paid add-on), else null. |
aiExtract | object | AI structured work details (paid add-on), else null. |
observedAt | string | ISO 8601 timestamp of when the record was collected. |
error | string | null on success. On a failed run, a single item with a populated error field is written instead. |
Example output record
Real record from a live run (input {"maxPermits":5,"withAiSummary":true,"withAiExtract":true}):
{"permitNumber": "B200506822","permitType": "PERMIT – EXPRESS PERMIT PROGRAM","permitStatus": "ACTIVE","workType": "Electrical Work","address": "1746 N STOCKTON DR, CHICAGO, IL","issueDate": "2026-08-12","reportedCost": 1000,"totalFee": 100,"ownerName": "CHICAGO SPECIAL EVENTS MANAGEMENT","contractorName": "HAUGER ELECTRIC","contractorType": "ELECTRICAL CONTRACTOR","contractorCity": "GLENDALE HEIGHTS","ward": "43","communityArea": "7","latitude": "41.9144421056552","longitude": "-87.6322626481453","aiSummary": "This permit authorizes electrical work at 1746 N Stockton Dr, Chicago, IL, involving the installation of a new permanent 100 AMP service disconnecting means with one circuit.","observedAt": "2026-08-14T07:22:30.607Z","error": null}
Run via API and CLI
Start a run and wait for it to finish, then read the dataset. Replace <TOKEN> with your Apify API token.
Run synchronously and get dataset items in one call:
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~chicago-building-permits-scraper/run-sync-get-dataset-items?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"workType":"ROOF","minCost":50000,"maxPermits":50}'
Start a run asynchronously:
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~chicago-building-permits-scraper/runs?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"permitType":"PERMIT - NEW CONSTRUCTION","issuedFrom":"2026-01-01","maxPermits":200}'
Apify CLI:
apify call scrapers_lat/chicago-building-permits-scraper \--input '{"ward":"43","maxPermits":25}'
Fetch results
Every run writes to a dataset. Fetch items as JSON, CSV, or Excel by changing format:
# JSONcurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"# CSVcurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"# Paginate large datasetscurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"
<DATASET_ID> is returned as defaultDatasetId in the run object. Use offset and limit to page through large result sets. clean=true drops empty and internal fields.
Billing and limits
- Pay per result. You are charged per permit returned (
resultevent). See the pricing tab for the current per-result price. - Paid AI add-ons.
withAiSummaryandwithAiExtractare optional, require a paid Apify plan, and are billed per record only when they return usable output. - No charge on failure. If a run errors, the actor writes a single item with a populated
errorfield and does not charge for it. Empty runs cost nothing. - Spend cap respected. Set
maxTotalChargeUsdon the run; once reached, the actor stops emitting and charging further billable results. - Free Apify plans are capped at 10 records per run. Upgrade for higher
maxPermits.
FAQ and troubleshooting
A run returned 0 records. Why?
The filter combination matched no permit. Loosen filters (remove ward or widen the date range). Zero-result runs are not charged.
How do I find leads by contractor or owner?
Use contractorName or ownerName, or put a company name in query to search across all contacts and the description at once.
Why are the AI fields null? The matching add-on was off, you are on a free account, or the permit had no work description to summarize. AI fields are never invented.
Do I need a Socrata app token?
No. The source is keyless. A free appToken only raises the rate limit for very large pulls.
Why is contractorName empty on some permits?
Some permit types (for example simple sign or scaffolding permits) list no contractor. Missing values are returned as null.
Is this an official City of Chicago tool? No. This actor is independent and has no affiliation with the City of Chicago. It reads only data that is publicly available through the City's open data portal. Use it in accordance with the portal terms.
Related scrapers
- NYC DOB Permits Scraper: New York City building permits with contractors and owners.
- USA Contractor Licenses Scraper: Contractor license records across US states.
- OSHA Inspections & Violations Scraper: US workplace safety inspections and violations.
- USA Business Licenses Scraper: US local business license records.
- Google Maps Business Leads Scraper: Local business leads with contacts from Google Maps.
More scrapers at scrapers.lat
Built and maintained by scrapers.lat, where we publish scrapers for US and Latin American public platforms: company registries, government data, finance, e-commerce and more. Browse the catalog or request a custom scraper at scrapers.lat.
Independent tool, not affiliated with the City of Chicago. Accesses only publicly available open data. Use in accordance with the data portal terms of service.
