SF Building Permit Scraper
Pricing
from $3.00 / 1,000 results
SF Building Permit Scraper
Scrape the official San Francisco Department of Building Inspection permit dataset. Search/filter by permit type, status, neighborhood, district, zip, use, construction type, cost, or date; lookup by permit number, property address, or assessor block/lot. Free Socrata API, no login.
Pricing
from $3.00 / 1,000 results
Rating
0.0
(0)
Developer
Crawler Bros
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Scrape the official San Francisco Department of Building Inspection (DBI) building permit dataset. Search or filter San Francisco building permits by permit type, status, neighborhood, supervisor district, zip code, use, construction type, estimated cost, or filed/issued date — or look up permits by permit number, property address, or assessor block & lot. Powered by the public SF Open Data (Socrata) API. No login, no API key, no proxy required.
What this actor does
- Four modes:
search(filter/browse),byPermitNumber(exact permit lookup),byAddress(lookup by street number + street name),byBlockLot(lookup by assessor's block & lot) - Rich filters: permit type, status, neighborhood, supervisor district, zip code, existing/proposed use, existing/proposed construction type, estimated-cost range, filed-date range, issued-date range, description keyword, geographic radius around a lat/lon point
- Special-project toggles: ADU (Accessory Dwelling Unit), fire-only permit, site permit, structural notification, voluntary soft-story seismic retrofit, reroofing
- Full-text search across the permit's work description and other text fields
- Every permit application — one record per permit, spanning new construction, alterations/repairs, demolitions, signs, grading, and more
- Geo data — latitude/longitude, neighborhood, supervisor district, zip code, block/lot
- Empty fields are omitted — a permit missing a completion date or a construction-type code simply has no such field, never a placeholder
Output per permit record
permitNumber— DBI permit number (usually one row per permit, but DBI's own dataset occasionally publishes more than one row for the same permit number — e.g. a permit renewal alongside its original record;rowIdis the actual unique key)permitType,permitTypeDefinition— DBI permit classification code and definitionstatus,statusDate— current status and when it was last setfiledDate,issuedDate,completedDate,approvedDate,firstConstructionDocumentDate,permitCreationDate,lastPermitActivityDatedescription— free-text work descriptionstreetNumber,streetNumberSuffix,streetName,streetSuffix,unit,unitSuffix,fullAddresscity,state— always San Francisco, CAblock,lot,blockLot— assessor parcel identifiersneighborhood— SF planning analysis neighborhoodsupervisorDistrict— Board of Supervisors district (1-11)zipcodelatitude,longitudenumberOfExistingStories,numberOfProposedStoriesestimatedCost,revisedCost(USD)existingUse,existingUnits,proposedUse,proposedUnitsplansetsexistingOccupancy,proposedOccupancy— building-code occupancy classificationexistingConstructionType,existingConstructionTypeDescription,proposedConstructionType,proposedConstructionTypeDescriptionstructuralNotification,voluntarySoftStoryRetrofit,fireOnlyPermit,sitePermit,adu,primaryAddressFlag,reroof— booleans, only present when the flag appliestidfCompliance— Transportation Impact Development Fee compliance code (Y/R/P/E)applicationSubmissionMethodpointSource— how the property's geolocation point was derivedrecordId— DBI's internal record identifier (links related permit applications)dataAsOf— when SF Open Data last refreshed this rowrowId— stable Socrata row identifiersourceUrl— direct link to this exact record on SF's open-data APIrecordType: "buildingPermit",scrapedAt
Input
| Field | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (filter/browse), byPermitNumber, byAddress, or byBlockLot |
searchQuery | string | – | Full-text search across description/address text fields (mode=search) |
descriptionKeyword | string | – | Case-insensitive substring match on the work description |
permitNumbers | array | – | Exact permit numbers to fetch (mode=byPermitNumber) |
streetNumber / streetName | string | – | Street number + name for an address lookup (mode=byAddress) |
streetSuffix / unit | string | – | Optional narrowing for an address lookup (mode=byAddress) |
block / lot | string | – | Assessor block & lot for a parcel lookup (mode=byBlockLot) |
permitType | string | any | One of 9 DBI permit types (new construction, alterations, demolitions, signs, etc.) |
status | string | any | One of 23 current permit statuses (issued, complete, expired, filed, etc.) |
neighborhood | string | any | One of 41 SF analysis neighborhoods |
supervisorDistrict | string | any | Board of Supervisors district 1-11 |
zipcode | string | any | One of 30 SF zip codes |
existingUse / proposedUse | string | any | One of 99 standardized property-use categories |
existingConstructionType / proposedConstructionType | string | any | Building-code construction-type classification |
filedDateFrom / filedDateTo | string | – | ISO date range (YYYY-MM-DD) on the filed date |
issuedDateFrom / issuedDateTo | string | – | ISO date range (YYYY-MM-DD) on the issued date |
minEstimatedCost / maxEstimatedCost | number | – | Estimated construction cost bounds (USD, 0–1,000,000,000) |
nearLatitude / nearLongitude | number | – | Only include permits within nearRadiusMeters of this point (mode=search) |
nearRadiusMeters | number | 500 | Radius in meters for the geographic filter (1–5000); only applies when both lat/lon are set |
aduOnly | boolean | false | Only include Accessory Dwelling Unit permits |
fireOnlyPermitOnly | boolean | false | Only include fire-department-only permits |
sitePermitOnly | boolean | false | Only include site permits (large multi-phase projects) |
structuralNotificationOnly | boolean | false | Only include permits with a structural notification |
voluntarySoftStoryRetrofitOnly | boolean | false | Only include voluntary soft-story seismic retrofit permits |
reroofOnly | boolean | false | Only include reroofing permits |
sortBy | string | filedDateDesc | Sort order — filed date, issued date, status date, or estimated cost |
appToken | string | – | Optional free Socrata app token for higher rate limits |
maxItems | int | 50 | Hard cap on emitted records (1–10000) |
Example: browse the latest filed permits
{"mode": "search","sortBy": "filedDateDesc","maxItems": 20}
Example: lookup by permit number
{"mode": "byPermitNumber","permitNumbers": ["201903226060"]}
Example: all permits at a specific address
{"mode": "byAddress","streetNumber": "760","streetName": "14th","streetSuffix": "St"}
Example: all permits on a specific assessor parcel
{"mode": "byBlockLot","block": "3537","lot": "027"}
Example: high-value new-construction permits in a neighborhood
{"mode": "search","permitType": "1","neighborhood": "South of Market","minEstimatedCost": 500000,"maxItems": 100}
Example: voluntary soft-story seismic retrofit permits
{"mode": "search","voluntarySoftStoryRetrofitOnly": true,"maxItems": 200}
Example: ADU permits filed in 2024
{"mode": "search","aduOnly": true,"filedDateFrom": "2024-01-01","filedDateTo": "2024-12-31","maxItems": 200}
Example: permits within 500m of a specific point (e.g. Civic Center)
{"mode": "search","nearLatitude": 37.7793,"nearLongitude": -122.4193,"nearRadiusMeters": 500,"maxItems": 100}
Use cases
- Real estate research — check permit history, open work, and estimated construction cost for a property before buying or renting
- Contractor / architect prospecting — find recent new-construction or alteration permits by neighborhood, use type, or cost range
- Seismic-safety tracking — monitor voluntary soft-story retrofit uptake across the city
- ADU market research — track Accessory Dwelling Unit permit volume and location trends
- Journalism & policy research — investigate construction trends, demolition activity, or permit-processing timelines
- Academic research — bulk-export permit data for urban-planning or housing studies
FAQ
What is the data source?
The San Francisco Department of Building Inspection's "Building Permits" dataset, published on SF Open Data (Socrata, dataset ID i98e-djp9) and refreshed regularly by the city.
Is this affiliated with the City and County of San Francisco or DBI? No. This is an independent, third-party actor built on SF's public open-data API.
Why does the actor use data.sfgov.org instead of sfdbi.org?
sfdbi.org is a legacy domain that now redirects to www.sf.gov, which sits behind a WAF challenge that blocks direct automated access. The DBI's actual permit records are published in full by the city on its official open-data platform, data.sfgov.org — the same underlying dataset that powers SF DBI's public permit lookups — so this actor reads directly from that authoritative source instead.
What does estimatedCost vs revisedCost mean?
estimatedCost is the cost declared at filing time; revisedCost reflects any cost revision made during plan review or construction. When no revision was recorded, only estimatedCost appears.
What does tidfCompliance mean?
The Transportation Sustainability/Impact Development Fee compliance code: Y (paid/compliant), R (reduced), P (pending), or E (exempt). Only present when DBI recorded a value.
Why do some construction-type fields show unusual values like V, B, or III instead of 1–5?
This mirrors data-entry inconsistencies present in the source dataset itself — DBI sometimes records construction type using building-code Roman-numeral/letter designations instead of the standard numeric 1–5 codes. The actor passes through whatever value DBI's system recorded rather than guessing a normalization.
Why do some permits have no structuralNotification/voluntarySoftStoryRetrofit/fireOnlyPermit/sitePermit/reroof field?
These are opt-in flags DBI only records as Y when they apply; when a permit doesn't carry the flag, the field is omitted rather than shown as false.
How does the address lookup (byAddress) work?
Supply streetNumber and streetName (required together); optionally add streetSuffix and/or unit to narrow the match further. Matching on streetName is case-insensitive and exact (not fuzzy), matching DBI's own address indexing.
How fresh is the data?
SF Open Data refreshes this dataset regularly (the city notes that as of December 2024 it publishes new/changed rows incrementally). Each record includes a dataAsOf field showing when it was last synced upstream from DBI's permit-tracking system.
Are there rate limits? The Socrata API allows unauthenticated access with reasonable limits. Supplying a free Socrata app token (optional) raises those limits, but the actor works without one.