Philadelphia Building Permits - Contractor & Property Data avatar

Philadelphia Building Permits - Contractor & Property Data

Pricing

from $0.03 / 1,000 philadelphia permit records

Go to Apify Store
Philadelphia Building Permits - Contractor & Property Data

Philadelphia Building Permits - Contractor & Property Data

Philadelphia building & trade permits (public open data, 584,800 permits, 2007-today): type, description, approved scope, issue and completion dates, owner of record, full contractor block, address, council district and geocode.

Pricing

from $0.03 / 1,000 philadelphia 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

a day ago

Last modified

Categories

Share

Every building and trade permit the City of Philadelphia has issued since 2007, 584,800 of them, current through this week.

Each permit names the contractor who pulled it and their full business address, the property owner of record and the OPA account, the approved scope of work, the issue and completion dates, and the exact property it covers - including the council district, census tract and coordinates.

Low cost

From $0.00005 per record, down to $0.00003 at Gold Pay-per-event: you are charged per record delivered, and nothing for the query.

What you get

FieldMeaning
permitNumber / permitTypeThe permit, and its type
permitDescription / approvedScopeOfWork / typeOfWorkWhat the work is, in the filer's own words
statusCompleted 491,228 / Expired 50,163 / Issued 37,875, plus the amendment workflow states
issuedDate / completedDate / mostRecentInspectionIssue, completion and the latest inspection
contractorName / contractorAddress1 / contractorCity / contractorState / contractorZipThe contractor, with the full business address - name populated on 78% of permits
opaOwner / opaAccountNumber / parcelIdProperty owner of record, OPA account and parcel
address / unit / zip / censusTract / councilDistrictThe property
latitude / longitudeCoordinates
category / numberOfStoriesClassification. category is the residential/commercial split on every row; numberOfStories where the source carries it

Modes

  • rows (default) - permits matching your filters.
  • aggregate - one count row per group: by permit type, status, system of record, category, council district or issue year.

Example inputs

One permit in full - permitNumber is a substring match, so the whole number returns the single permit.

{ "permitNumber": "PP-2026-013242" }

Every permit a contractor has pulled - contractor matches on the name, which is present on 78% of permits.

{ "contractor": "BEST", "maxResults": 25 }

Work issued in one council district this month - councilDistrict is a number (1-10) and issuedFrom is a date.

{ "councilDistrict": 5, "issuedFrom": "2026-09-01", "maxResults": 25 }

Volume by permit type - one count per type; both the HANSEN codes and the ECLIPSE names land in the one column.

{ "mode": "aggregate", "groupBy": "permitType" }

What is being built in a council district - councilDistrict is a number (1-10); mode=aggregate with groupBy=permitType breaks the district down by trade.

{ "councilDistrict": 5, "mode": "aggregate", "groupBy": "permitType" }

New zoning and building work this month - issuedFrom opens the issue-date window.

{ "issuedFrom": "2026-09-01" }

One register, two systems of record

This is the single most confusable thing about this dataset, and it will cost you if you filter by type without knowing it.

Philadelphia's permit data is a union of two systems that are being migrated from one to the other, tagged in system:

HANSEN 364,847 ECLIPSE 219,953

The older system uses short codes and the newer one uses plain English names, and both vocabularies land in the same permitType column:

HANSENECLIPSE
BP_NEWCNST 8,947Building 12,559
PP_PLUMBNG 93,691Plumbing 60,586
EP_ELECTRL 65,334Electrical 41,404
ZP_ZON/USE 21,555Zoning 24,286

So a filter for permitType=Plumbing returns 60,586 permits, not the 154,277 that plumbing work actually accounts for - you are reading ECLIPSE's share of it. Filter system alongside permitType when you need the complete picture for a trade, or leave both blank and filter on description instead.

What is not here

Four columns exist in the source and are delivered, but are filled on so few rows that no reliable query can be built on them, and this listing makes no claim about them:

ColumnPopulated
useCategories3.8%
numberOfUnits4.5%
occupancyType6.9%
coIssuedDate1.6%
unitType0.5%

There is no occupancy classification, unit count or certificate-of-occupancy data worth selling on this source, so occupancy is not advertised as a feature. The columns are delivered where the source fills them.

Example output

One permit - permitNumber=PP-2026-013242 returns this record:

{
"platform": "philly-permits",
"source": "philadelphia-permits",
"mode": "rows",
"groupKey": "",
"groupCount": "",
"groupBy": "",
"permitNumber": "PP-2026-013242",
"permitType": "Plumbing",
"permitDescription": "Plumbing Permit",
"category": "Residential",
"typeOfWork": "Alterations",
"approvedScopeOfWork": "Piping and instlling (6) water cloests, (6) lavs, (3) bathtubs, (2)kitchen sink, (1) storm drain, (2) washing machines, (1) hub drain (2) washing machines (2) water heaters",
"status": "Issued",
"system": "ECLIPSE",
"issuedDate": "2026-09-22",
"completedDate": "",
"mostRecentInspection": "",
"coIssuedDate": "",
"coRequired": "",
"applicantType": "Professional / Tradesperson",
"contractorName": "Michael Jen",
"contractorAddress1": "Michael Jen\r\n708 SOUTH 08TH STREET\r\n2ND FLOOR\r\nPHILADELPHIA, PA 19147\r\nUSA",
"contractorAddress2": "",
"contractorCity": "",
"contractorState": "",
"contractorZip": "",
"address": "1006 N MARSHALL ST",
"unit": "",
"unitType": "",
"zip": "19123-1309",
"censusTract": "014100",
"councilDistrict": "5",
"opaAccountNumber": "141000099",
"opaOwner": "SIU KING YUEN",
"parcelId": "251483",
"latitude": "2697780.80932022",
"longitude": "242584.91036913998",
"numberOfUnits": "",
"numberOfStories": "",
"useCategories": "",
"occupancyType": "",
"parentJobId": "907281302",
"zoningPermitJobId": "",
"denialDate": "",
"denialDocumentLink": "",
"coDocumentLink": "",
"sourceUpdatedAt": "2026-09-23"
}

mode=aggregate, groupBy=permitType - one row per group:

PP_PLUMBNG 93,691
EP_ELECTRL 65,334
BP_ALTER 62,651
Plumbing 60,586
Electrical 41,404
BP_MECH 28,689

Every permit a contractor has pulled - contractor=BEST:

ZP-2026-009412 2026-09-22 Issued Zoning 726 S 7TH ST

New zoning and building work this month - issuedFrom=2026-09-01:

ZP-2026-009412 2026-09-22 Issued Zoning 726 S 7TH ST
ZP-2026-008546 2026-09-22 Issued Zoning 301 W OLNEY AVE
ZP-2026-007728 2026-09-22 Issued Zoning 3815 BROOKVIEW RD

Source

Counts below are a live snapshot - the service is republished in place, so exact figures move between reads. The order of magnitude and the ratios are stable.

City of Philadelphia, Department of Licenses & Inspections, published on the City's ArcGIS open-data service as PERMITS - public open data, no login and no key. Permits range from 2007-01-01 to the current week.

The row count is not stable. During a single day's work on this listing the service was caught mid-republish: it returned 935,503 records, then 584,800 after the item was modified, with every column shrinking by the same 0.625 factor. That signature - uniform across all fields rather than concentrated at the old end - says the whole register was re-cut, not that old permits were dropped. The figures here are the post-republish ones. If the City restores the window these numbers move again.

Output

Every record carries the same key set regardless of mode - the permit fields plus the aggregate columns (groupKey, groupCount, groupBy), which are "" outside aggregate mode. Every record carries sourceUpdatedAt, the date the City last edited the layer.

  • Philadelphia L&I Violations - the code violations, inspections and complaints raised against these same properties.
  • Philly311 Service Requests - what residents reported about them.