Chicago Building Permits Scraper avatar

Chicago Building Permits Scraper

Pricing

$0.01 / 1,000 building permits

Go to Apify Store
Chicago Building Permits Scraper

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é

Maxime Dupré

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

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.

📋 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

  1. Choose Search permits for a filtered Chicago search, or Look up a permit for one exact published permit ID.
  2. Add any date, status, classification, location, contact, project-text, or cost filters that fit your question.
  3. Choose All matching permits or New permits since prior run in Search mode.
  4. 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.
  5. 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

FieldTypeWhat it does
targetstringChoose search for matching permits or permit for one exact permit lookup. Fields for the other target are ignored.
searchModestringChoose all for all matching permits or newSincePreviousRun for permits newly available since the prior run. If omitted, all matching permits are used.
projectSearchstringOptional text to find in the published project description.
issueDateFromdate stringOptional first issue date to include, in YYYY-MM-DD format.
issueDateTodate stringOptional last issue date to include, in YYYY-MM-DD format.
permitStatusesarray of stringsOptional published permit statuses to include. Leave empty to include every status.
permitTypesarray of stringsOptional published permit types to include. Leave empty to include all permit types.
reviewTypesarray of stringsOptional published review types to include. Leave empty to include all review types.
workTypesarray of stringsOptional published work types to include. Leave empty to include all work types.
wardsarray of stringsOptional Chicago ward numbers to include. Leave empty to include all wards.
communityAreasarray of stringsOptional Chicago community area numbers to include. Leave empty to include all community areas.
streetstringOptional street text to match in the published job address.
addressstringOptional full address text to match in the published job address.
ownerstringOptional owner name text to match in published permit contacts.
applicantstringOptional applicant name text to match in published permit contacts.
contractorstringOptional contractor name text to match in published permit contacts.
contactNamestringOptional name text to match in any published contact entry.
contactZipstringOptional ZIP code to match in published contact entries.
minProjectCostnumberOptional lowest reported project cost to include, in USD.
maxProjectCostnumberOptional highest reported project cost to include, in USD.
maxItemsintegerOptional stop after this many matching permits. Leave empty to return all available results until the source is exhausted.
permitIdstringRequired 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

FieldTypeWhat it does
datasetURL stringLinks 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

FieldTypeWhat it does
permitIdstringPublished identifier for the Chicago building permit.
statusstringPublished permit status.
milestonestringPublished permit milestone.
classificationobjectPublished permit, review, and work classifications.
classification.permitTypestringPublished permit type.
classification.reviewTypestringPublished review type.
classification.workTypestringPublished work classification.
timingobjectPublished dates and normalized processing duration.
timing.applicationDatedate stringDate when the permit application started.
timing.issueDatedate stringDate when the permit was issued.
timing.processingDurationDaysnumberNormalized days from application to issue.
propertyobjectPublished job location and property details.
property.addressobjectPublished address parts for the job.
property.address.fullstringFull published job address.
property.address.streetNumberstringPublished street number, when present.
property.address.streetDirectionstringPublished street direction, when present.
property.address.streetNamestringPublished street name, when present.
property.address.streetSuffixstringPublished street suffix, when present.
property.address.citystringCity in the published job address, when present.
property.address.statestringState in the published job address, when present.
property.address.zipCodestringZIP code in the published job address, when present.
property.wardintegerPublished Chicago ward number.
property.communityAreaintegerPublished Chicago community area number.
property.propertyIdentifiersarray of objectsPublished property identifiers.
property.propertyIdentifiers[]objectOne property identifier.
property.propertyIdentifiers[].typestringSource label for the property identifier.
property.propertyIdentifiers[].valuestringPublished property identifier value.
property.censusAreaobjectPublished census area details.
property.censusArea.tractstringPublished census tract, when present.
property.censusArea.blockGroupstringPublished census block group, when present.
property.censusArea.blockstringPublished census block, when present.
property.coordinatesobjectNormalized published geographic coordinates.
property.coordinates.latitudenumberPublished latitude in decimal degrees.
property.coordinates.longitudenumberPublished longitude in decimal degrees.
projectobjectPublished work description and reported project cost.
project.descriptionstringPublished description of the planned work.
project.reportedCostnumberNormalized project cost reported by the source.
feesobjectPublished fee amounts and payment states.
fees.totalobjectTotal fee breakdown.
fees.total.amountnumberTotal published fee amount.
fees.total.paidnumberPublished amount already paid in the total breakdown.
fees.total.unpaidnumberPublished amount still unpaid in the total breakdown.
fees.total.waivednumberPublished amount waived in the total breakdown.
fees.buildingobjectBuilding fee breakdown.
fees.building.amountnumberPublished building fee amount.
fees.building.paidnumberPublished building amount already paid.
fees.building.unpaidnumberPublished building amount still unpaid.
fees.building.waivednumberPublished building amount waived.
fees.zoningobjectZoning fee breakdown.
fees.zoning.amountnumberPublished zoning fee amount.
fees.zoning.paidnumberPublished zoning amount already paid.
fees.zoning.unpaidnumberPublished zoning amount still unpaid.
fees.zoning.waivednumberPublished zoning amount waived.
fees.otherobjectOther fee breakdown.
fees.other.amountnumberPublished other fee amount.
fees.other.paidnumberPublished other amount already paid.
fees.other.unpaidnumberPublished other amount still unpaid.
fees.other.waivednumberPublished other amount waived.
contactsarray of objectsSource-published people and roles linked to the permit.
contacts[]objectOne source-published contact entry.
contacts[].rolestringSource-published role for the contact.
contacts[].namestringSource-published contact name, when present.
contacts[].mailingLocationobjectSource-published mailing locality, when present.
contacts[].mailingLocation.citystringMailing city, when published.
contacts[].mailingLocation.statestringMailing state, when published.
contacts[].mailingLocation.zipCodestringMailing ZIP code, when published.
sourceobjectSource record and search details used for verification.
source.providerstringName of the source that published the record.
source.datasetstringName of the official Chicago dataset.
source.datasetUrlURL stringOfficial URL for the Chicago dataset.
source.recordIdstringSource identifier when it differs from the permit ID.
source.recordUrlURL stringDirect URL for the permit in the official source.
source.searchContextobjectSearch settings applied to the result.
source.searchContext.targetstringTarget used for the run: search or permit.
source.searchContext.projectSearchstringProject text used by the search, when present.
source.searchContext.issueDateFromdate stringFirst issue date used by the search, when present.
source.searchContext.issueDateTodate stringLast issue date used by the search, when present.
source.searchContext.permitStatusesarray of stringsPermit status values used by the search.
source.searchContext.permitTypesarray of stringsPermit type values used by the search.
source.searchContext.reviewTypesarray of stringsReview type values used by the search.
source.searchContext.workTypesarray of stringsWork type values used by the search.
source.searchContext.wardsarray of stringsWard values used by the search.
source.searchContext.communityAreasarray of stringsCommunity area values used by the search.
source.searchContext.streetstringStreet text used by the search, when present.
source.searchContext.addressstringAddress text used by the search, when present.
source.searchContext.ownerstringOwner text used by the search, when present.
source.searchContext.applicantstringApplicant text used by the search, when present.
source.searchContext.contractorstringContractor text used by the search, when present.
source.searchContext.contactNamestringContact name text used by the search, when present.
source.searchContext.contactZipstringContact ZIP code used by the search, when present.
source.searchContext.minProjectCostnumberLowest reported project cost used by the search, when present.
source.searchContext.maxProjectCostnumberHighest reported project cost used by the search, when present.
source.searchContext.permitIdstringExact permit ID used by the lookup, when present.
source.retrievedAtdate-time stringTime 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 🫡

Made with ❤️ by Maxime Dupré