Chicago Building Violations
Pricing
$0.10 / 1,000 chicago violation records
Chicago Building Violations
Chicago building code violations (public open data, 2.03M records, daily): the violation code, description and ordinance, the inspector's comments, the inspection that produced it, and the property address with lat/lon. Filter by status/category/bureau/code/date or pull the daily change stream.
Pricing
$0.10 / 1,000 chicago violation records
Rating
0.0
(0)
Developer
Wenhao Yang
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Chicago publishes every building-code violation it writes - over two million of them - as open data. This actor turns that register into a charged-per-record lookup, filter and aggregate tool: pull the violations at an address, sweep a bureau's caseload, isolate the open cases, or follow the daily change stream to see what the buildings department touched today.
Built for: property and title diligence, real-estate and construction underwriting, code-compliance screening, and anyone who needs the code-enforcement record behind a Chicago address - not a keyword match against a street name.
What it covers
2,027,808 violations - every code violation on file, spanning the department's own bureaus:
| Bureau | Violations |
|---|---|
| Conservation | 1,333,299 |
| Special Task Force | 148,295 |
| Elevator | 135,695 |
| Demolition | 119,476 |
| Electrical | 42,820 |
| Boiler | 40,416 |
| Plumbing | 39,617 |
| New Construction | 39,121 |
| Ventilation | 36,631 |
| Refrigeration | 32,032 |
| Special Inspection Program / Signs / Iron / Water / Construction Equipment | ~60,400 |
and why each inspection happened - COMPLAINT (1,430,270), PERIODIC (492,812), PERMIT (102,133), REGISTRATION (2,593).
Each violation carries real depth, not just a code:
- the violation code (100% populated -
CN190019,EV1110,CN061014, ), its plain-language description (2,013,116 rows), and the municipal ordinance citation it falls under (1,968,752) - the inspector's own comments on the finding (1,837,142 rows)
- the inspection that produced it: number, category, status, and the bureau that ran it
- the property: full street address (100%, 174,821 distinct addresses), street number/direction/name/type, property group, SSA, and lat/lon (2,025,788)
The fine print that matters
Status is exactly three source values - OPEN (1,159,140, still outstanding), COMPLIED (861,525, resolved) and NO ENTRY (7,143, inspector couldn't gain access) - matched as exact values. The daily change stream is real: violation_last_modified_date is a per-row timestamp, so mode=delta returns what the department actually touched since a date (1,210 rows in the last 7 days).
Two source quirks are handled honestly. The inspection_waived column is 'N' on all 2.03M rows - a dead field, not surfaced. And the violation_location column (a short free-text note like "rear porch") is filled on only ~49% of rows - surfaced as-is and never pitched as a location field; the real geocoding is latitude/longitude, present on 99.9%.
One boundary stated plainly: Chicago's building-permit register stores street parts separately and has no address column, so the violationpermit relationship is a fuzzy address / lat-lon match, not an id join. This actor gives you the violation record complete; joining it to a permit is address work, not a key lookup.
Typical questions
- "Every open violation at 200 E Garfield Blvd."
- "Elevator bureau violations filed this year."
- "Complaint-driven inspections that FAILED in Chicago."
- "Violations under code EV1110."
- "What did the buildings department change since yesterday?" (
mode=delta) - "Aggregate the register by bureau, category or status."
Inputs
| Input | What it does |
|---|---|
mode | rows (default) / delta (change stream) / aggregate |
status / category / inspectionStatus | open vs resolved; why inspected; inspection outcome |
bureau | which department unit |
violationCode | exact code |
address / streetName | where |
dateFrom / dateTo / changedSince | violation-date range, and the change window |
groupBy | aggregate over status / category / bureau / inspectionStatus / code |
maxResults | cap records (default 200) |
Default run = the 200 most recent violations - fast for the daily auto-test. For a targeted query add a filter; for a broad view use aggregate.
Low cost
From $0.0001 per record - billed only for the rows you use, at the platform floor. Cost scales with what you pull, not with the size of the register, and because each record is metered individually there's no per-run charge cap to hit on a big pull.
The traps in this register are the silent ones. The status column carries a value - NO ENTRY - that means the inspector couldn't look, which a filter written for open/closed quietly files under neither; the change timestamp and the violation date are different columns, so "what the department touched since yesterday" and "what was filed since yesterday" are different questions (1,210 rows were modified in the last seven days, while 614 new ones were filed - the two axes move at different rates), and a single date filter conflates them; and the location note is present on less than half the file, so treating it as the location drops half the register. Normalizing the three-valued status, the separate change column and the half-empty note into a schema where an address / status=OPEN / bureau query returns exactly the violations you mean - and mode=delta returns the true daily delta - is the actual product. Every pull is integrity-checked against the register's known shape, so a degraded source fails loudly instead of returning bad rows.
Source
- City of Chicago: Building Violations - the city's full violation register, refreshed daily. Public open data. Records are the city's own published fields; a violation is an alleged code violation, not a court finding.