Cincinnati Building Permits - Permits & Named Contacts
Pricing
from $0.03 / 1,000 cincinnati building permit records
Cincinnati Building Permits - Permits & Named Contacts
Cincinnati building permits (180,521, 2010 to today): type, work class and status as code and label, dates, address with PIN, and the company on the permit. A contacts mode adds the named owner, contractor and trade parties.
Pricing
from $0.03 / 1,000 cincinnati building permit records
Rating
0.0
(0)
Developer
Wenhao Yang
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
17 hours ago
Last modified
Categories
Share
Every building permit the City of Cincinnati has issued, straight from the City's own open data portal. ~180.6k permits covering 2010 to this week (as of 2026-09-28), plus a depth layer of 444,304 named contacts - the owner, contractor, architect, engineer and trade contacts on each permit.
Low cost
From $0.00005 per record, down to $0.00003 at Gold. Pay only for the records you actually receive - the whole register stays queryable, you are never billed for the scan behind it.
What you get
Permits - one row per permit filing:
- Which permit - the permit number, the type both as a code and as a plain label (Building, HVAC, Plumbing, Fire Protection Systems, Wrecking, Signs, Elevator, ), the work class (existing or new, again both ways), and the permit class (residential, commercial, or non-standard code book)
- Status - both the raw code (
CLOSED,ISSUED,ROUTE,WITHDRWN,APPLIED,EXPIRED, ) and the City's cleaned label ("Permit Finaled", "Permit Issued", "In Review") - When - applied, issued, completed, certificate-of-occupancy issued, and expires dates, each where the permit has one
- Where - the site address, city, ZIP, PIN, the neighborhood, and latitude and longitude
- What - the work description, the proposed occupancy use, the estimated cost, the square footage, the number of units, and the fee
- Who - the company on the permit (the contractor, or the literal
OWNER), plus a link to the City's permit record
Contacts - one row per named party on a permit, each enriched with its parent permit's type, status, address, company and issue date, so a contact row answers "who was on which job" without a second lookup.
Modes
- permits (default) - the permit register, 2010 to today
- contacts - the named parties on a permit - ⚠️ the source carries these for permits from 2013 to 2019 only (see the notes below)
- aggregate - counts by permit type, status, work class, neighborhood or permit class
Filters
Permit number, permit type, status, work class, permit class, description, address, city, ZIP, neighborhood, company name, PIN, applied-date range and issued-date range. In contacts mode also: relationship and contact name.
Example inputs
One company's permits
{ "companyName": "SECO ELECTRIC", "maxResults": 50 }
Permits issued this year
{ "status": "ISSUED", "issuedFrom": "2026-01-01", "maxResults": 100 }
Permits in one neighborhood, one type
{ "neighborhood": "OAKLEY", "permitType": "Building", "maxResults": 50 }
Every named party on one permit
{ "mode": "contacts", "permitNumber": "2016P06260" }
All the contractors the source recorded, 2013-2019
{ "mode": "contacts", "relationship": "CONTRACTOR", "maxResults": 100 }
Permit volume by type
{ "mode": "aggregate", "groupBy": "permitType" }
Example output
One permit - permitNumber=2026P06867 (empty keys omitted for brevity; every
row carries the full key set):
{"platform": "cincinnati-permits","source": "city-of-cincinnati-building-permits","mode": "permits","recordType": "permit","groupKey": "","groupCount": "","groupBy": "","permitNumber": "2026P06867","description": "Fire Protection Systems","appliedDate": "2026-07-21","issuedDate": "2026-08-11","completedDate": "2026-09-04","expiresDate": "2027-08-11","address": "4861 DUCK CREEK RD","city": "CINCINNATI","state": "OH","zip": "45227","jurisdiction": "CINCINNATI","permitClass": "OBC","status": "CLOSED","statusMapped": "Permit Finaled","workClass": "CALT","workClassMapped": "Existing","permitType": "CBPCFAP","permitTypeMapped": "Fire Protection Systems","companyName": "SECO ELECTRIC CO INC","estimatedCost": "2650","totalSqFt": "0","units": "0","pin": "005100070050","proposedUse": "B","fee": "519.33","link": "http://cagis.hamilton-co.org/opal/apd.aspx?QSPerm=2026P06867","latitude": "39.164705899533715","longitude": "-84.4138167585839","neighborhood": "MADISONVILLE","sourceUpdatedAt": "2026-09-25"}
One contact, mode=contacts, permitNumber=2016P06260 - note the
parent* fields, which come from the related permit:
{"mode": "contacts","recordType": "contact","permitNumber": "2016P06260","relationship": "OWNER","contactName": "SOUTHWEST OHIO REGIONAL T","contactAddress1": "602 MAIN ST STE 1100","contactAddress2": "CINCINNATI OH","contactZip": "45202","contactAppliedDate": "2026-07-02","parentPermitType": "CBPCFAP","parentStatus": "ISSUED","parentAddress": "1401 BANK ST","parentCompany": "EXECUTIVE SECURITY SYSTEMS INC","parentIssuedDate": "2016-09-22","sourceUpdatedAt": "2026-09-25"}
mode=aggregate, groupBy=permitType:
HVAC 48,933Building 44,904Plumbing Permits 44,636Fire Protection Systems 11,186Excavation/Fill 9,193Misc. Structures 6,725Wrecking 5,741
Notes on the data, from the source
- 🔴 The contacts layer covers 2013 to 2019 only, and this is the single most
important thing to know about this actor. Measured 2026-09-28 by sampling
250-400 permits per year and joining: contacts cover 2013-2019 at ~100%
and 2021 through 2026 at 0%. The contact table's permit numbers run from
2012P00493to2019P11609and nothing beyond, so 2020 is a partial year - by permit number it is 0%, and of the 10,032 permits the register dates to 2020 only 985 (10%) carry a pre-2020 number that could have contacts. Somode=permits, which includes the company name the register itself carries on 89% of rows, is the default and spans the whole register;mode=contactsis a 2013-2019 depth layer, not a universal join. - 🔴 Costs and sizes are stored as TEXT, so this actor deliberately offers no
cost or size filter.
estimatedCost,totalSqFtandunitsare text columns in the source, and the obvious workaround is a silent disaster: a quoted comparison such asestimatedCost >= '100000'is accepted by the API and compared as a string, where'200000'sorts below'30000'- it would return 148,778 of ~180.6k permits for a $100k floor. Asking for a cost filter here raises an error instead. The columns are still returned, as the text the source stores. - 🔴 Three columns wrap their value in literal double quotes: the company name on 160,614 rows (89%), the PIN on 180,096 (99.8%) and the proposed use on all ~180.6k. The quotes are stripped on output, and stripped from your search text, so a company search matches whether or not you typed them.
- The permit number is not unique. ~180.6k rows carry 162,861 distinct permit numbers - one permit is filed once per trade. The row is the unit.
- The Status column is served twice on purpose, and the mapped form is only
partly cleaned.
statusMappedmerges three raw codes into one label -ISSUED,ENGRCHNGandTEMPCOFOall read "Permit Issued" - and for sixteen other raw codes it repeats the code unchanged (APP_EXP,APRV_NR,XCLOSED,W/REFUND, ). That is why the raw column carries 24 distinct codes and the mapped column 22. No raw code has an empty mapped value; the filter matches either form, so a caller can search the code they see or the label. community_council_neighborhoodis empty on all ~180.6k rows - a dead column in the source. It is not returned and is not in the schema.- The contractor on the permit is sometimes the owner. The company column
carries the literal
OWNERon some rows; it is served as the source stores it rather than being blanked, because that is the underlying fact. - Some coverage is partial: the completed date is on 80.3% of permits, the expires date on 92.0%, the certificate-of-occupancy issued date on 17.5%, the square footage on 31.2%, and the estimated cost and units are 0 on 22,298 and 74,904 rows respectively.
- Invalid filter inputs (a
%in a search, a ZIP with no digits, a malformed date, a cost filter, or a key this actor does not implement) are rejected rather than passed to the source.
Coverage and freshness
Cincinnati building permits, 2010-01-04 to the present, kept current by the
City. The newest permit issue date at the time of writing was 2026-09-25. Every
record carries sourceUpdatedAt; the actor also carries count guards on both
tables and a whole-corpus field-coverage guard, so a source that collapses or
changes shape fails loudly instead of returning an empty page as success.