Cincinnati Building Permits - Permits & Named Contacts avatar

Cincinnati Building Permits - Permits & Named Contacts

Pricing

from $0.03 / 1,000 cincinnati building permit records

Go to Apify Store
Cincinnati Building Permits - Permits & Named Contacts

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

Wenhao Yang

Maintained by Community

Actor 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,933
Building 44,904
Plumbing Permits 44,636
Fire Protection Systems 11,186
Excavation/Fill 9,193
Misc. Structures 6,725
Wrecking 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 2012P00493 to 2019P11609 and 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. So mode=permits, which includes the company name the register itself carries on 89% of rows, is the default and spans the whole register; mode=contacts is 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, totalSqFt and units are text columns in the source, and the obvious workaround is a silent disaster: a quoted comparison such as estimatedCost >= '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. statusMapped merges three raw codes into one label - ISSUED, ENGRCHNG and TEMPCOFO all 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_neighborhood is 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 OWNER on 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.