Chicago Building Permits Scraper
Pricing
$0.01 / 1,000 building permits
Chicago Building Permits Scraper
Search the official City of Chicago building-permit dataset by date, status, work type, location, contact, cost, or exact permit ID. Save structured permit details, project scope, fees, contacts, and source links for construction and property research.
Pricing
$0.01 / 1,000 building permits
Rating
0.0
(0)
Developer
Maxime Dupré
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
🏗️ Find Chicago building permits by location, work, or permit ID
Construction teams, property researchers, and civic-data developers can search the official City of Chicago Building Permits dataset and save matching permits as structured dataset rows. Review permit status, milestone, work type, project cost, job address, fees, source-published contacts, and source links in one place. Use filters for one Chicago search, or look up one exact permit ID.
- Search the city records with City of Chicago Building Permits and review matching permits.
- Review construction work with Chicago Construction Permits and compare each project's scope and cost.
- Find a job by address with City of Chicago Permits Search by Address and inspect its source-linked details.
- Group matching records with Chicago Permits by Ward for ward-level project review.
- Find roofing work with Chicago Roof Permits and compare the published scope and cost.
- Check a published status with Chicago Permit Status and review its milestone.
- Open one exact record with Chicago Permit Lookup using its permit ID.
📋 Structured Chicago permit rows
Every saved row represents one matching source permit. It keeps the published permit ID, status, milestone, classification, dates, job location, project description, reported cost, fee breakdown, contact roles, and source details. Dates, amounts, durations, and coordinates use consistent JSON types where the source provides them. Chicago values that are not published remain unavailable; the Actor does not invent contact or project data.
▶️ Search Chicago permits your way
Run flow
- Choose Search permits for a filtered Chicago search, or Look up a permit for one exact published permit ID.
- Add any date, status, classification, location, contact, project-text, or cost filters that fit your question.
- Choose All matching permits or New permits since prior run in Search mode.
- Set Maximum permits when you want an upper bound on saved permits. Leave it empty to return all available results until the source is exhausted.
- Start the run and open the default dataset to review the saved rows and their source links.
Search fields narrow one Chicago query. For a repeat search, newSincePreviousRun asks for permits newly available since the prior run. A source item is saved on its first eligible match; if it appears again through another submitted value, later matches are ignored and the saved row keeps the first match's source context.
⚙️ Input
Input fields
| Field | Type | What it does |
|---|---|---|
target | string | Choose search for matching permits or permit for one exact permit lookup. Fields for the other target are ignored. |
searchMode | string | Choose all for all matching permits or newSincePreviousRun for permits newly available since the prior run. If omitted, all matching permits are used. |
projectSearch | string | Optional text to find in the published project description. |
issueDateFrom | date string | Optional first issue date to include, in YYYY-MM-DD format. |
issueDateTo | date string | Optional last issue date to include, in YYYY-MM-DD format. |
permitStatuses | array of strings | Optional published permit statuses to include. Leave empty to include every status. |
permitTypes | array of strings | Optional published permit types to include. Leave empty to include all permit types. |
reviewTypes | array of strings | Optional published review types to include. Leave empty to include all review types. |
workTypes | array of strings | Optional published work types to include. Leave empty to include all work types. |
wards | array of strings | Optional Chicago ward numbers to include. Leave empty to include all wards. |
communityAreas | array of strings | Optional Chicago community area numbers to include. Leave empty to include all community areas. |
street | string | Optional street text to match in the published job address. |
address | string | Optional full address text to match in the published job address. |
owner | string | Optional owner name text to match in published permit contacts. |
applicant | string | Optional applicant name text to match in published permit contacts. |
contractor | string | Optional contractor name text to match in published permit contacts. |
contactName | string | Optional name text to match in any published contact entry. |
contactZip | string | Optional ZIP code to match in published contact entries. |
minProjectCost | number | Optional lowest reported project cost to include, in USD. |
maxProjectCost | number | Optional highest reported project cost to include, in USD. |
maxItems | integer | Optional stop after this many matching permits. Leave empty to return all available results until the source is exhausted. |
permitId | string | Required when target is permit; enter one exact published Chicago permit ID. |
Leave optional filters empty when you want the source's full available range. issueDateFrom and issueDateTo use calendar dates. permitStatuses, permitTypes, reviewTypes, and workTypes use the values published by Chicago.
Successful search input
This is the public input from a successful current-beta search run:
{"target": "search","searchMode": "all","projectSearch": "roof","maxItems": 5}
🧾 Output
Run output
| Field | Type | What it does |
|---|---|---|
dataset | URL string | Links to the default Apify dataset that contains the successful Chicago building permit rows. |
Search and exact permit lookup use the same dataset row shape. Fields can be omitted when Chicago does not publish a value for that source row.
Dataset row fields
| Field | Type | What it does |
|---|---|---|
permitId | string | Published identifier for the Chicago building permit. |
status | string | Published permit status. |
milestone | string | Published permit milestone. |
classification | object | Published permit, review, and work classifications. |
classification.permitType | string | Published permit type. |
classification.reviewType | string | Published review type. |
classification.workType | string | Published work classification. |
timing | object | Published dates and normalized processing duration. |
timing.applicationDate | date string | Date when the permit application started. |
timing.issueDate | date string | Date when the permit was issued. |
timing.processingDurationDays | number | Normalized days from application to issue. |
property | object | Published job location and property details. |
property.address | object | Published address parts for the job. |
property.address.full | string | Full published job address. |
property.address.streetNumber | string | Published street number, when present. |
property.address.streetDirection | string | Published street direction, when present. |
property.address.streetName | string | Published street name, when present. |
property.address.streetSuffix | string | Published street suffix, when present. |
property.address.city | string | City in the published job address, when present. |
property.address.state | string | State in the published job address, when present. |
property.address.zipCode | string | ZIP code in the published job address, when present. |
property.ward | integer | Published Chicago ward number. |
property.communityArea | integer | Published Chicago community area number. |
property.propertyIdentifiers | array of objects | Published property identifiers. |
property.propertyIdentifiers[] | object | One property identifier. |
property.propertyIdentifiers[].type | string | Source label for the property identifier. |
property.propertyIdentifiers[].value | string | Published property identifier value. |
property.censusArea | object | Published census area details. |
property.censusArea.tract | string | Published census tract, when present. |
property.censusArea.blockGroup | string | Published census block group, when present. |
property.censusArea.block | string | Published census block, when present. |
property.coordinates | object | Normalized published geographic coordinates. |
property.coordinates.latitude | number | Published latitude in decimal degrees. |
property.coordinates.longitude | number | Published longitude in decimal degrees. |
project | object | Published work description and reported project cost. |
project.description | string | Published description of the planned work. |
project.reportedCost | number | Normalized project cost reported by the source. |
fees | object | Published fee amounts and payment states. |
fees.total | object | Total fee breakdown. |
fees.total.amount | number | Total published fee amount. |
fees.total.paid | number | Published amount already paid in the total breakdown. |
fees.total.unpaid | number | Published amount still unpaid in the total breakdown. |
fees.total.waived | number | Published amount waived in the total breakdown. |
fees.building | object | Building fee breakdown. |
fees.building.amount | number | Published building fee amount. |
fees.building.paid | number | Published building amount already paid. |
fees.building.unpaid | number | Published building amount still unpaid. |
fees.building.waived | number | Published building amount waived. |
fees.zoning | object | Zoning fee breakdown. |
fees.zoning.amount | number | Published zoning fee amount. |
fees.zoning.paid | number | Published zoning amount already paid. |
fees.zoning.unpaid | number | Published zoning amount still unpaid. |
fees.zoning.waived | number | Published zoning amount waived. |
fees.other | object | Other fee breakdown. |
fees.other.amount | number | Published other fee amount. |
fees.other.paid | number | Published other amount already paid. |
fees.other.unpaid | number | Published other amount still unpaid. |
fees.other.waived | number | Published other amount waived. |
contacts | array of objects | Source-published people and roles linked to the permit. |
contacts[] | object | One source-published contact entry. |
contacts[].role | string | Source-published role for the contact. |
contacts[].name | string | Source-published contact name, when present. |
contacts[].mailingLocation | object | Source-published mailing locality, when present. |
contacts[].mailingLocation.city | string | Mailing city, when published. |
contacts[].mailingLocation.state | string | Mailing state, when published. |
contacts[].mailingLocation.zipCode | string | Mailing ZIP code, when published. |
source | object | Source record and search details used for verification. |
source.provider | string | Name of the source that published the record. |
source.dataset | string | Name of the official Chicago dataset. |
source.datasetUrl | URL string | Official URL for the Chicago dataset. |
source.recordId | string | Source identifier when it differs from the permit ID. |
source.recordUrl | URL string | Direct URL for the permit in the official source. |
source.searchContext | object | Search settings applied to the result. |
source.searchContext.target | string | Target used for the run: search or permit. |
source.searchContext.projectSearch | string | Project text used by the search, when present. |
source.searchContext.issueDateFrom | date string | First issue date used by the search, when present. |
source.searchContext.issueDateTo | date string | Last issue date used by the search, when present. |
source.searchContext.permitStatuses | array of strings | Permit status values used by the search. |
source.searchContext.permitTypes | array of strings | Permit type values used by the search. |
source.searchContext.reviewTypes | array of strings | Review type values used by the search. |
source.searchContext.workTypes | array of strings | Work type values used by the search. |
source.searchContext.wards | array of strings | Ward values used by the search. |
source.searchContext.communityAreas | array of strings | Community area values used by the search. |
source.searchContext.street | string | Street text used by the search, when present. |
source.searchContext.address | string | Address text used by the search, when present. |
source.searchContext.owner | string | Owner text used by the search, when present. |
source.searchContext.applicant | string | Applicant text used by the search, when present. |
source.searchContext.contractor | string | Contractor text used by the search, when present. |
source.searchContext.contactName | string | Contact name text used by the search, when present. |
source.searchContext.contactZip | string | Contact ZIP code used by the search, when present. |
source.searchContext.minProjectCost | number | Lowest reported project cost used by the search, when present. |
source.searchContext.maxProjectCost | number | Highest reported project cost used by the search, when present. |
source.searchContext.permitId | string | Exact permit ID used by the lookup, when present. |
source.retrievedAt | date-time string | Time when the source record was retrieved. |
Successful current-beta search row
This complete row is from the successful run for the input shown above:
{"permitId": "B200481856","status": "ACTIVE","milestone": "INSPECTION ELIGIBLE","classification": {"permitType": "PERMIT – EXPRESS PERMIT PROGRAM","reviewType": "EXPRESS PERMIT PROGRAM","workType": "Reroofing"},"timing": {"applicationDate": "2026-08-06","issueDate": "2026-08-06","processingDurationDays": 0},"property": {"address": {"full": "3517 N KILPATRICK AVE","streetNumber": "3517","streetDirection": "N","streetName": "KILPATRICK AVE"},"ward": 30,"communityArea": 15,"propertyIdentifiers": [{"type": "PIN","value": "1322302010"}],"censusArea": {"tract": "151000"},"coordinates": {"latitude": 41.94523804406035,"longitude": -87.74380597065314}},"project": {"description": "SCOPE: ROOF REPLACEMENT. AREA: 2288 SQ. FT. ROOF COVERING: ASPHALT SHINGLES. LOCATION: ROOFING. IL ROOFING CONTRACTOR LICENSE: 104.01959.","reportedCost": 10000},"fees": {"total": {"amount": 450,"paid": 450,"unpaid": 0,"waived": 0},"building": {"amount": 450,"paid": 450,"unpaid": 0,"waived": 0},"zoning": {"amount": 0,"paid": 0,"unpaid": 0,"waived": 0},"other": {"amount": 0,"paid": 0,"unpaid": 0,"waived": 0}},"contacts": [{"role": "OWNER","name": "SILVA JOSÉ","mailingLocation": {"city": "CHICAGO","state": "IL","zipCode": "60641"}},{"role": "WEB APPLICANT","name": "ALTAMIRANDA SANTIAGO","mailingLocation": {"city": "CHICAGO","state": "IL","zipCode": "60007"}},{"role": "GENERAL CONTRACTOR","name": "SLOG GROUP LLC","mailingLocation": {"city": "ELK GROVE VILLAGE","state": "IL","zipCode": "60007"}}],"source": {"provider": "City of Chicago","dataset": "Building Permits","datasetUrl": "https://data.cityofchicago.org/d/ydr8-5enu","recordId": "N2934356","recordUrl": "https://data.cityofchicago.org/resource/ydr8-5enu.json?%24where=id+%3D+%27N2934356%27","searchContext": {"target": "search","projectSearch": "roof"},"retrievedAt": "2026-08-07T20:45:14.352Z"}}
💳 Pricing
How billing works
This Actor uses pay-per-event pricing. One billing event is tied to each matching building permit saved to the dataset. Set maxItems when you want an upper bound on saved permits and their permit events. Check the current event price on the Store page before you run it.
🔌 Integrations
Dataset and API
Open the default dataset link after a run to review the saved rows. Standard Apify dataset and API access lets you consume the permit fields and source links in your own workflow.
Video walkthrough
❓ FAQ
What source does this Actor use?
It searches the official City of Chicago Building Permits dataset. Each row keeps the dataset URL and, when available, a direct source record URL for review.
Can I search by address or permit ID?
Yes. Use address or street for a search, or choose target: "permit" and enter one exact permitId.
What does leaving Maximum permits empty do?
It returns all available results until the source is exhausted. Set maxItems when you want a smaller upper bound.
Can I request only new permits?
Yes. In a search run, set searchMode to newSincePreviousRun to request permits newly available since the prior run. Use all for every permit that matches the current filters.
Does this cover Cook County or other cities?
No. This Actor searches the City of Chicago Building Permits dataset only. It does not claim coverage for Cook County, other municipalities, or other source datasets.
Are phone numbers or email addresses included?
No. The Actor returns contact roles, names, and mailing locality when Chicago publishes them. It does not add phone, email, or other third-party contact enrichment.
What if Chicago does not publish a field?
That field can be omitted from the row. The Actor keeps source-published values and does not invent missing project, property, fee, contact, or coordinate data.
What happens if no permit matches?
The dataset may contain no saved permit rows. Broaden a filter, check the date range, or try an exact permit ID when you need to check one known record.
Can one run hold several independent searches?
No. One run represents one configured Chicago search or one exact permit lookup. Values inside a filter list are part of that one query.
📝 Changelog
0.0: Initial release
🆘 Support
For issues, questions, or feature requests, file a ticket and I'll fix or implement it in less than 24h 🫡
🔗 Related Actors
- U.S. Census Geocoder — match permit addresses and coordinates to Census geography for mapping and area analysis.
- PropertyShark Scraper — add public property, building, and sale-history context to a real estate review.
- Realtor Scraper — compare public for-sale, rental, sold, or pending listings for a property search.
- Chicago Building Permits & Contractor Leads Scraper — compare another Chicago permit search with project and source-published contact details.
- Chicago Building Permits Scraper (Contractors, Owners) — compare another Chicago permit collection with owner, contractor, cost, fee, and address fields.
Made with ❤️ by Maxime Dupré