Chicago Building Permits & Contractor Leads Scraper avatar

Chicago Building Permits & Contractor Leads Scraper

Pricing

Pay per event + usage

Go to Apify Store
Chicago Building Permits & Contractor Leads Scraper

Chicago Building Permits & Contractor Leads Scraper

πŸ—οΈ Find newly issued Chicago permits and export official project, fee, property, owner, applicant, designer, and contractor details for leads and analysis.

Pricing

Pay per event + usage

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 days ago

Last modified

Share

Turn Chicago's official building permit records into fresh construction intelligence and prospect lists.

This Apify Actor searches the City of Chicago Building Permits dataset, applies precise server-side filters, and exports one normalized permit per dataset row. Find newly issued solar, roofing, HVAC, electrical, demolition, renovation, and general construction projects without maintaining your own Socrata integration.

Each result can include the permit status and milestone, application and issue dates, address, work description, reported project cost, fee breakdown, ward, community area, PIN, coordinates, and every owner, applicant, design-professional, general-contractor, or electrical-contractor contact published by the city.

  • πŸ—οΈ Discover newly permitted projects.
  • πŸ‘· Identify named contractors and project contacts.
  • πŸ’΅ Prioritize work by reported cost and fees.
  • πŸ“ Segment activity by ward, community area, address, or contact ZIP.
  • πŸ” Schedule the same query to build a recurring permit lead feed.
  • πŸ”Ž Look up a specific permit number for verification.

What does this Chicago building permits scraper do?

The Actor queries Chicago's official public dataset ydr8-5enu through its Socrata API. It does not scrape a fragile visual page, require a login, or use a proxy.

You can search a rolling recent window or provide exact issue dates. Additional filters cover permit status, permit type, review type, work type, geography, reported project cost, and any of the five contact slots in the source.

Results are normalized for JSON, CSV, Excel, XML, RSS, and Parquet exports. Numeric values are emitted as numbers, dates use ISO timestamps, and contact slots become a consistent typed array.

Who is it for?

Contractors and subcontractors

Find active projects that may need roofing, solar, HVAC, electrical, concrete, painting, landscaping, security, waste removal, or other services. Filter to a trade or minimum project value before sending records to a CRM.

Construction suppliers and service vendors

Track projects that may need materials, rentals, dumpsters, insurance, financing, inspections, or job-site services. Scheduled searches make it easy to review new permits every day or week.

Real-estate and construction analysts

Measure permit activity by date, ward, community area, work type, project value, and review process. Preserve the applied query and source URL for reproducible analysis.

Insurers, lenders, and due-diligence teams

Look up an address or permit number, review declared work and project cost, and identify the owner, applicant, designer, or contractor names published on the permit.

Civic-data developers

Use a stable Actor interface instead of implementing SoQL escaping, pagination, retries, normalization, Apify datasets, and integrations yourself.

Why use this Actor?

  • βœ… Official source: data comes directly from the City of Chicago open-data API.
  • βœ… Deep Chicago fields: detailed fees, milestones, review types, contacts, PINs, census tracts, and coordinates are retained.
  • βœ… Useful filtering: filters run on the source before records are transferred.
  • βœ… Typed output: money, durations, ward values, and coordinates are numbers.
  • βœ… Auditable records: every item includes the applied query, dataset ID, retrieval time, and direct source URL.
  • βœ… Automation ready: run manually, through the API, on a schedule, by webhook, or through MCP.
  • βœ… No proxy setup: the source is a public government API.

What data can you extract?

Data groupExample fieldsHow it helps
Permit identitypermitNumber, permitStatus, permitMilestoneVerify and track a permit
ClassificationpermitType, reviewType, workTypeSegment projects and trades
DatesapplicationStartDate, issueDate, processingTimeDaysMonitor freshness and processing
Propertyaddress, ward, communityArea, pinListRoute and map opportunities
ProjectworkDescription, reportedCostQualify project scope and value
Feespaid, unpaid, waived, subtotals, totalFeeAnalyze permit economics
Contactsowner, applicant, designer, general/electrical contractorBuild source-backed lead context
Geographycensus tract, latitude, longitude, projected coordinatesMap and aggregate activity
Provenancequery, sourceDatasetId, sourceUrl, retrievedAtAudit and reproduce results

The source usually provides names and mailing locality fields, not phone numbers or email addresses. This Actor does not invent or infer missing contact data.

How much does it cost to scrape Chicago building permits?

Pricing is pay per event: a small run-start charge plus one charge for each permit saved. The exact amount appears in the Apify Console before a run and may vary by your Apify pricing tier.

The Actor uses a $0.005 start event. Formula-driven permit prices are $0.000027442 on FREE, $0.000023863 on BRONZE, $0.000018613 on SILVER, $0.000014318 on GOLD, and $0.00001 on PLATINUM or DIAMOND.

Apify tierPrice per permit1,000 permits plus start
FREE$0.000027442about $0.0324
BRONZE$0.000023863about $0.0289
SILVER$0.000018613about $0.0236
GOLD$0.000014318about $0.0193
PLATINUM$0.00001about $0.0150
DIAMOND$0.00001about $0.0150

A 20-permit first run is intentionally small. Use maxItems to cap spending, then increase it after checking the result density for your filters.

You are not charged a per-permit event for source rows that are not saved.

How to scrape Chicago building permits

  1. Open the Actor in Apify Console.
  2. Leave dates empty to search permits issued in the rolling last 30 days, or choose a date range.
  3. Optionally add status, permit type, work type, ward, cost, address, or contact filters.
  4. Set Maximum permits to a small number for your first run.
  5. Click Start.
  6. Review the permit table in the default dataset.
  7. Export results or connect the dataset to your downstream system.
  8. Create an Apify schedule if you want a recurring fresh-permit feed.

For an exact lookup, enter permitNumber. The Actor then ignores the date range and searches that permit number directly.

Input parameters

ParameterTypeDescription
permitNumberstringExact Chicago permit number
startDatestringEarliest issue date, YYYY-MM-DD
endDatestringLatest issue date, YYYY-MM-DD
permitStatusstring[]Exact official statuses
permitTypestring[]Exact official permit types
workTypestring[]Exact official work types
reviewTypestring[]Exact official review types
wardstring[]Chicago ward numbers
communityAreastring[]Official community area numbers
addressTextstringCase-insensitive street-address text
contactZipstring[]ZIP in any published contact slot
contactNamestringName text in any contact slot
minReportedCostnumberMinimum reported project cost
maxReportedCostnumberMaximum reported project cost
maxItemsintegerMaximum permits to save, 1–50,000

All active filter groups are combined with AND. Multiple values inside one list are combined as alternatives.

Example inputs

Recent active permits

{
"permitStatus": ["ACTIVE"],
"maxItems": 25
}

Solar permit leads

{
"permitStatus": ["ACTIVE"],
"workType": ["Small-Scale Solar PV System"],
"minReportedCost": 10000,
"maxItems": 100
}

Exact permit lookup

{
"permitNumber": "B200477271",
"maxItems": 1
}

Ward-based high-value monitor

{
"ward": ["1", "27", "42"],
"minReportedCost": 1000000,
"maxItems": 250
}

Output example

{
"sourceRecordId": "N2915993",
"permitNumber": "B200477271",
"permitStatus": "ACTIVE",
"permitMilestone": "INSPECTIONS",
"permitType": "PERMIT – EXPRESS PERMIT PROGRAM",
"reviewType": "EXPRESS PERMIT PROGRAM",
"applicationStartDate": "2026-07-03T00:00:00.000",
"issueDate": "2026-07-13T00:00:00.000",
"processingTimeDays": 10,
"address": "9038 S MARSHFIELD AVE",
"city": "Chicago",
"workType": "Small-Scale Solar PV System",
"reportedCost": 48721,
"totalFee": 300,
"ward": 21,
"communityArea": 73,
"ownerName": "QUINCY JONES",
"generalContractorName": "CERTIFIED ELECTRIC LLC",
"electricalContractorName": "CERTIFIED ELECTRIC LLC",
"contacts": [
{
"type": "OWNER",
"name": "QUINCY JONES",
"city": "CHICAGO",
"state": "IL",
"zipCode": "60620"
}
],
"sourceDatasetId": "ydr8-5enu",
"sourceUrl": "https://data.cityofchicago.org/resource/ydr8-5enu.json?...",
"retrievedAt": "2026-07-15T00:00:00.000Z"
}

Optional fields are omitted when Chicago's source row does not provide them.

Contractor lead workflow

A practical recurring workflow is:

  1. Choose one or more work types relevant to your service.
  2. Add a recent issue-date range and ACTIVE status where appropriate.
  3. Apply a minimum reported cost to prioritize larger projects.
  4. Schedule the Actor daily or weekly.
  5. Export permitNumber, address, description, cost, and contractor/contact fields.
  6. Deduplicate downstream by sourceRecordId or permitNumber.
  7. Review the official source before outreach.

Permit contacts are public-record context, not consent or a guarantee that a person wants marketing messages. Apply your own outreach and privacy rules.

Tips for better results

  • 🎯 Start with 25 records and inspect official spellings for work, permit, and review types.
  • πŸ“† Use narrow date windows for recurring schedules so each run focuses on fresh activity.
  • πŸ’° Combine minReportedCost with a work type to prioritize commercially relevant projects.
  • 🧭 Use ward or community area filters for territory-based sales teams.
  • πŸ” Use addressText without abbreviations when the source may spell streets differently.
  • πŸ‘· Search contactName when verifying a known contractor's permit activity.
  • πŸ†” Prefer exact permitNumber for one-record due diligence.
  • πŸ“¦ Raise maxItems only after confirming that your query returns the desired records.

Pagination and data freshness

Results are ordered by newest issue date and source row ID. The Actor reads the official API in bounded pages and stops at maxItems.

Chicago controls publication timing and corrections. A permit may be updated after it first appears, and status or milestone fields may change. Scheduled monitoring should use stable identifiers when comparing datasets.

A very large query can take longer and may observe upstream changes between pages. Narrow date windows are best for repeatable operational feeds.

Integrations

Google Sheets and Excel

Export the dataset to CSV or XLSX, or connect Apify to a spreadsheet automation. Use one row per permit for filtering and territory assignment.

CRMs

Send successful run dataset items to HubSpot, Salesforce, Pipedrive, or another CRM through Make, Zapier, webhooks, or custom code. Map permitNumber as an external key to reduce duplicates.

Maps and BI tools

Load latitude, longitude, ward, community area, work type, and project cost into Tableau, Power BI, Looker Studio, QGIS, or a warehouse.

Alerts and scheduling

Run the Actor on an Apify schedule and send a webhook when new results are ready. A downstream step can compare permit IDs and notify a territory owner.

Run with the Apify API

Replace YOUR_APIFY_TOKEN with your token.

Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/chicago-building-permits-scraper').call({
permitStatus: ['ACTIVE'],
minReportedCost: 100000,
maxItems: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

from apify_client import ApifyClient
import os
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/chicago-building-permits-scraper').call(run_input={
'permitStatus': ['ACTIVE'],
'minReportedCost': 100000,
'maxItems': 100,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)

cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~chicago-building-permits-scraper/runs?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"permitStatus":["ACTIVE"],"minReportedCost":100000,"maxItems":100}'

Use with MCP and AI assistants

Connect the Actor to Claude Code:

$claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/chicago-building-permits-scraper"

For Claude Desktop, Cursor, or VS Code, add this MCP server configuration:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/chicago-building-permits-scraper"
}
}
}

Example prompts:

  • β€œFind up to 50 active Chicago solar permits from the last 30 days and summarize project costs.”
  • β€œLook up permit B200477271 and list every contractor and applicant.”
  • β€œMonitor high-value permits in wards 1, 27, and 42 and prepare a CRM import.”
  • β€œMap recent permits by community area and work type.”

Data quality and limitations

  • The Actor only returns fields published in Chicago's official dataset.
  • Contact slots usually contain names and mailing locality, not phone or email.
  • contactZip refers to contact mailing ZIPs; the source does not expose a dedicated property ZIP field.
  • Official labels and spellings can change as Chicago updates its schema.
  • Some permits omit cost, coordinates, contacts, or fee components.
  • A contact name may represent a person or company exactly as entered in the source.
  • The Actor does not enrich, score, validate, or infer permit data.
  • Upstream maintenance or anonymous API rate limits can temporarily delay a run.

The Actor reads a public government open-data API. Public availability does not remove your responsibility to follow applicable laws, contractual obligations, privacy requirements, and outreach rules.

Use permit and contact information for legitimate purposes. Do not treat a public-record name or address as consent for unsolicited communication. Avoid sensitive profiling, harassment, discrimination, or automated decisions that require additional legal safeguards.

This documentation is general information, not legal advice.

Troubleshooting

Why did my run return no permits?

The exact combination may have no matching source rows. Remove filters one at a time, check date order, and verify official capitalization/spelling for list filters. Try a small unfiltered recent run first.

Why is a contact phone or email missing?

Chicago's permit dataset does not normally publish those fields. The Actor preserves official contact names, types, cities, states, and ZIP codes but does not fabricate enrichment.

Why was my input rejected?

Dates must use YYYY-MM-DD; the start date cannot be later than the end date; and minimum project cost cannot exceed maximum project cost.

Why did a large run slow down?

The public API may rate-limit bursts. The Actor retries temporary errors with backoff. Narrow the issue-date range or lower maxItems for faster recurring jobs.

Frequently asked questions

Does it support permit-number lookup?

Yes. Set permitNumber to an exact Chicago permit number. Date filters are intentionally ignored for that lookup.

Does it cover Cook County or other cities?

No. This Actor is intentionally optimized for the City of Chicago dataset. It does not claim equivalent fields or coverage outside that source.

Can I schedule it?

Yes. Apify schedules are ideal for daily or weekly fresh-permit monitoring. Use stable IDs to deduplicate downstream.

Are all contacts contractors?

No. Contacts are typed by the source and may include owners, web applicants, design professionals, general contractors, electrical contractors, or other roles.

Can I export to CSV or Excel?

Yes. Open the dataset after a run and choose CSV, XLSX, JSON, XML, RSS, or another supported format.

Is a proxy required?

No. The Actor uses Chicago's public Socrata API directly.

Source and provenance

The source dataset is City of Chicago Building Permits. Every output row includes:

  • the official dataset identifier;
  • the SoQL filter applied by the Actor;
  • a direct API URL for the permit;
  • the retrieval timestamp.

These fields help reviewers verify a record and help data teams reproduce a collection rule.

Choose this Actor when the official Chicago permit is the core record and source-backed project details matter most.

Support

If a valid Chicago permit appears in the official dataset but is missing or incorrectly normalized, open an issue from the Actor page. Include a small input, the permit number when available, and the run ID so the behavior can be reproduced.