Skip to content

thumpersecure/4philly

Repository files navigation

4PHILLY

Philadelphia property record — unified, live, drift-aware

Build License PWA Backend Data

Open the app · Report a bug · Coverage gaps


What this is

One unified Philadelphia property record. Type any address or OPA number — get business licenses, open violations, violation history, 311 complaints, permits, building certifications, and your City Council district with councilmember contact info, all pulled live from the city's own data.

Every data point is pulled from Eclipse (the authoritative L&I backend behind li.phila.gov) and Carto (the historical open-data mirror at phl.carto.com). When they disagree, 4PHILLY flags it. Eclipse always wins.

Note

4PHILLY runs entirely in your browser. No server. No analytics. No account. Your lookups don't leave your device except to hit the city's public APIs.


Try it

Drop any of these into the lookup bar at the top of the app:

Input What it pulls
315 N 12th St address-based lookup
1900 Market St high-rise example
The Sterling partial-name match
OPA account number OPA-anchored (most reliable)

Tip

OPA account numbers beat address strings for reliability — but they aren't permanent. Parcels can be re-numbered on splits, merges, or condo conversions. 4PHILLY stores coordinates from each successful lookup so it can automatically resolve re-numbered parcels via the DOR Parcel layer and coordinate proximity, then redirect you to the new OPA. You can also verify any property on Atlas.


Features

What it does
Live data Eclipse ArcGIS feature services + Carto SQL API, pulled at lookup time
Drift detection Side-by-side compare; divergent rows highlighted red
Status decoding OPEN, COMPLIED, CLOSED, CLOSEDCASE, RESOLVE — only COMPLIED is real compliance1
Council resolution District councilmember name, email, phone, committee assignments, L&I Committee flagging
OPA fallback If a saved OPA goes stale, resolves via DOR Parcel geometry, coordinate proximity, or address
Atlas verification Direct link to the city's Atlas tool for independent confirmation
OPA-anchored Identity bound to OPA account, with lat/lng fallback for re-numbered parcels
PWA Installable on iOS and Android; works on desktop; offline shell
No backend Static site. Auditable. Forkable. Nothing between you and the city's APIs.

How it works

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#ffb000','primaryTextColor':'#000','primaryBorderColor':'#ffb000','lineColor':'#ffb000','secondaryColor':'#1a1a1a','tertiaryColor':'#000'}}}%%
flowchart LR
    A[Address or OPA #] --> B{OPA resolve}
    B --> C[Eclipse ArcGIS<br/>authoritative]
    B --> D[Carto SQL<br/>historical mirror]
    C --> E[Drift comparator]
    D --> E
    E --> F[Unified record<br/>+ drift flags]
    B --> G[Council district<br/>from OPA data]
    G --> H[Councilmember<br/>+ L&I Committee flag]
Loading

Eclipse is what L&I inspectors actually use. Carto is what gets published to OpenDataPhilly. They drift. License expirations, violation status changes, and new complaints appear in Eclipse before — sometimes long before — Carto catches up.

4PHILLY shows you both.

OPA re-number fallback

OPA account numbers are not static. Parcels get split, merged, and re-numbered. When a saved or bookmarked OPA returns empty, 4PHILLY runs a three-tier fallback:

  1. DOR Parcel geometry — point-in-polygon query against the city's parcel boundary layer using stored coordinates
  2. OPA coordinate proximity — finds the nearest parcel within ~40m of the last known lat/lng
  3. Address re-resolution — falls back to the stored address string against the OPA location field

On success, the app redirects to the new OPA, updates saved bookmarks, and shows a banner with an Atlas verification link.


Tabs

The app surfaces six views per property:

  • Inspect — business & trade licenses, open violations, violation history, 311 complaints (last 24 months)
  • Drift — Eclipse vs. Carto side-by-side, divergent rows highlighted
  • Brief — plain-language read of the property record with legal citations
  • Records — permits and building certifications
  • Limits — what the data can't tell you, with source citations
  • Council — district councilmember contact info, committee assignments, L&I Committee flagging for properties with violations or expired licenses

Council district resolution

The Council tab resolves the property's OPA council_district_2024 field to the current councilmember and displays:

  • Councilmember name, email, phone, office location
  • Tappable email/phone links (mobile-optimized)
  • Committee assignments with chair roles highlighted
  • L&I Committee flag — when the property has open violations or an expired rental license, surfaces the L&I Committee Chair (currently Michael Driscoll, District 6) with direct contact info for escalation
  • All 7 at-large council members with contact info

Roster data sourced from phlcouncil.com standing committees page (embedded 2026-05-20).

A standalone Node.js module is also available at council/ for backend/agent use with point-in-polygon district resolution from coordinates.


What this can't tell you

Warning

Public data has limits. Some are city policy, some are technical, some are because the data simply doesn't exist in machine-readable form. Verify any claim before relying on it.

Gap Why
Inspector identity Not published in public feeds
Inspector notes Internal correspondence only
311 complainant identity Protected by policy
Re-inspection occurrence Status updates don't require a physical visit to record
Pre-archive violations Carto archive coverage varies; Eclipse retention varies
Sealed cases Excluded from public feeds entirely

See the Limits tab inside the app for the full list with source citations.


Install as a PWA

iOS (Safari)
  1. Open https://thumpersecure.github.io/4philly/ in Safari
  2. Tap the Share button
  3. Tap Add to Home Screen
  4. Confirm — 4PHILLY now lives on your home screen like a native app
Android (Chrome)
  1. Open the site in Chrome
  2. Tap the three-dot menu
  3. Tap Install app (or Add to Home screen)
  4. Confirm
Desktop (Chrome / Edge / Brave)
  1. Open the site
  2. Click the install icon at the right edge of the address bar
  3. Or: menu → Install 4PHILLY

Project structure

Click to expand
4philly/
├── index.html              # single-file PWA — all HTML, CSS, JS inline
├── manifest.json           # PWA manifest
├── sw.js                   # service worker (offline shell)
├── og-image.png            # social card
├── icon.svg                # app icon
├── 404.html                # GitHub Pages fallback
├── council/                # Node.js council district resolution module
│   ├── src/
│   │   ├── index.js        # main orchestrator — resolveCouncilMember()
│   │   ├── opa-client.js   # OPA Property API client
│   │   ├── geo.js          # point-in-polygon (ray-casting)
│   │   ├── district-resolver.js
│   │   ├── councilmember-lookup.js
│   │   ├── committee-flag.js
│   │   ├── cache.js        # LRU cache with TTL
│   │   └── format.js       # text + HTML output formatters
│   ├── data/
│   │   ├── districts.geojson      # 10 geographic district boundaries
│   │   ├── councilmembers.json    # full 17-member roster
│   │   └── committees.json        # L&I Committee chair config
│   └── tests/
│       └── council.test.js        # 12 unit tests (geo + cache)
├── tests/
│   └── opa-licenses.integration.test.mjs
└── README.md

Tech

HTML5 CSS3 JavaScript PWA GitHub Pages

No frameworks. No build step. Vanilla JS, fetch, and the city's public APIs. The entire frontend is a single index.html file with inline CSS and JS.

The council/ directory contains a standalone Node.js ESM module for server-side or agent use — same data, point-in-polygon resolution from coordinates instead of OPA field lookup.


GitHub Pages deployment

  • Pages deploy is automated with .github/workflows/deploy-pages.yml.
  • On main pushes, the workflow publishes from the repository root (.).
  • For branch layouts that publish from /docs, run the workflow manually and choose publish_source=docs.

Data sources

  • Eclipse ArcGISservices.arcgis.com/fLeGjb7u4uXqeF9q — authoritative for current state (violations, licenses, permits, building certs)
  • Carto SQL APIphl.carto.com — historical mirror (can lag Eclipse), also hosts 311 complaints (public_cases_fc)
  • OPA assessment layer — property identity anchor (parcel number, address, owner, coordinates, council district)
  • DOR Parcel layer — parcel polygon boundaries for re-numbered OPA resolution
  • phlcouncil.com — council roster, committee assignments, leadership (embedded snapshot)

Status semantics

A short field guide to the L&I status codes you'll see:

OPEN
Violation has been issued. No resolution yet.
COMPLIED
Inspector verified the condition was resolved. This is the only status that means what it sounds like.
CLOSED / CLOSEDCASE
Case is administratively closed. Could mean resolved, could mean dropped, could mean reassigned. Not confirmed compliance.
RESOLVE
Resolved via appeal. Compliance not confirmed by inspection.
ERROR
Data-entry anomaly. Not a real enforcement outcome.

Roadmap

  • Eclipse + Carto unified lookup
  • Drift detection (license + violation)
  • PWA install (iOS, Android, desktop)
  • 311 complaints (24-month window)
  • OPA-anchored identity
  • Permits and building certifications
  • Plain-language brief with legal citations
  • Council district resolution + councilmember contact
  • L&I Committee flagging for violations/licensing
  • OPA re-number fallback (DOR Parcel + coordinate + address)
  • Atlas verification links
  • Permit timeline view
  • Multi-property watchlist
  • CSV / JSON export
  • Diff alerts (subscribe to a property)
  • Print-ready brief (one-page PDF per property)
  • Real GIS shapefile for council districts (replace simplified boundaries in council module)

Contributing

Found drift the comparator missed? A status code that should decode differently? An edge case where Eclipse and Carto give the same answer but neither is correct? Council data out of date?

Open an issue with the OPA number and what you saw. PRs welcome.


License

MIT — see LICENSE.


Credits

Built by @thumpersecure.

Civic data is public. This tool makes it legible.

Open the app

4PHILLY is an independent civic tool. Not affiliated with the City of Philadelphia, L&I, OPA, or City Council.

Footnotes

  1. CLOSEDCASE in particular is ambiguous — a case can close without compliance being achieved. The COMPLIED status is the only one that means the underlying condition was resolved on inspection.

About

Look up any Philadelphia property’s L&I record — business licenses, open violations, and 311 complaints — pulled live from the city’s own data. Eclipse and Carto are cross-checked side by side, so you can see where the two sources disagree and which one to trust. Free, open-source, installable on phone or desktop.

Topics

Resources

License

Stars

Watchers

Forks

Contributors