NYC DOB Permits & Violations Scraper
Pricing
from $3.00 / 1,000 results
NYC DOB Permits & Violations Scraper
Scrape NYC Department of Buildings (DOB) construction permits and code violations from the public NYC Open Data API. Filter by borough, address, BIN, block/lot, job/permit type, permit status, violation category, and date range.
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
8 days ago
Last modified
Categories
Share
Scrape NYC Department of Buildings (DOB) construction permit and code violation records straight from the public NYC Open Data API. Search or filter by borough, address, Building Identification Number (BIN), tax block/lot, job/permit type, permit status, violation category, device number, and date range — or look up exact records by job number or violation number. HTTP-only via the public data.cityofnewyork.us Socrata API. No login, no cookies, no proxy required.
What this actor does
- Four modes:
permits,permitsByJob,violations,violationsByNumber - Two datasets: DOB Permit Issuance (~4 million permits) and DOB Violations (~2.5 million violations)
- Rich filters: borough, address (house number + street), BIN, block/lot, ZIP code, job type, permit type, permit subtype, work type, permit status, filing status, permittee license type, owner business type, residential-only, self-certified-only, non-profit-owner-only, violation category, violation type code, device number, ECB number, date range (by filing/issuance/expiration/job-start date for permits, or by issue/disposition date for violations), and free-text keyword search
- Derived fields: canonical
address, a computedbbl(Borough-Block-Lot) for violations, latitude/longitude for permits, zoning special districts for permits - Empty fields are omitted — a record never contains
null,"", or empty arrays
Output: per permit (mode = permits / permitsByJob)
recordType: "permit",scrapedAtborough,houseNumber,streetName,address,bin,block,lot,bblzipCode,communityBoard,councilDistrict,censusTract,ntaName,specialDistrict1,specialDistrict2jobNumber,jobDocNumber,jobType,permitType,permitSubtype,permitSequencepermitStatus,filingStatus,workType,buildingTyperesidential,selfCertified,ownerNonProfit— booleanssiteFill,oilGasfilingDate,issuanceDate,expirationDate,jobStartDate,dobRunDate—YYYY-MM-DDpermitteeName,permitteeBusinessName,permitteePhone,permitteeLicenseType,permitteeLicenseNumber,hicLicenseactAsSuperintendent,superintendentName,superintendentBusinessNamesiteSafetyManagerName,siteSafetyManagerBusinessNameownerBusinessType,ownerBusinessName,ownerName,ownerAddress,ownerCity,ownerState,ownerZipCodelatitude,longitudepermitSiNo,sourceUrl
Output: per violation (mode = violations / violationsByNumber)
recordType: "violation",scrapedAtisn— internal DOB BIS violation IDborough,bin,block,lot,bbl(derived — see FAQ)houseNumber,street,addressissueDate,dispositionDate—YYYY-MM-DDdispositionCommentsviolationTypeCode,violationType,violationNumber,violationCategory,numberdeviceNumber,ecbNumber(cross-reference to the DOB ECB Violations dataset — present on ~8% of records),descriptionsourceUrl
Input
| Field | Type | Default | Description |
|---|---|---|---|
mode | string | permits | permits / permitsByJob / violations / violationsByNumber |
borough | string | – | NYC borough (mode=permits / mode=violations) |
houseNumber | string | – | Street/house number, combine with streetName |
streetName | string | – | Street name (case-insensitive) |
bin | string | – | Building Identification Number |
block | string | – | Tax block number, combine with lot |
lot | string | – | Tax lot number, combine with block |
zipCode | string | – | 5-digit ZIP (mode=permits) |
jobType | string | – | DOB job type (mode=permits): A1/A2/A3/DM/NB/SG |
permitType | string | – | DOB permit type (mode=permits): AL/DM/EQ/EW/FO/NB/PL/SG |
permitSubtype | string | – | DOB permit subtype (mode=permits), e.g. BL/FN/SH/SP |
workType | string | – | DOB work type (mode=permits), e.g. BL/PL/MH/SP |
permitteeLicenseType | string | – | Permittee's professional license type (mode=permits), e.g. GC/MP/RA/PE |
ownerBusinessType | string | – | Property owner's business type (mode=permits), e.g. CORPORATION/INDIVIDUAL/NYCHA |
permitStatus | string | – | In Process / Issued / Re-Issued / Revoked (mode=permits) |
filingStatus | string | – | Initial / Renewal (mode=permits) |
residentialOnly | boolean | false | Only residential permits (mode=permits) |
selfCertifiedOnly | boolean | false | Only self-certified filings — no DOB plan review (mode=permits) |
nonProfitOwnerOnly | boolean | false | Only permits where the owner is flagged non-profit (mode=permits) |
dateField | string | filingDate | Which permit date column to filter/sort by (mode=permits) |
dateFrom | string | – | YYYY-MM-DD, inclusive lower bound |
dateTo | string | – | YYYY-MM-DD, inclusive upper bound |
keyword | string | – | Free-text search |
jobNumbers | array | – | DOB job numbers to fetch (mode=permitsByJob) |
violationCategory | string | – | Violation category (mode=violations) |
violationTypeCode | string | – | Violation type code, e.g. elevator/boiler/facade (mode=violations) |
deviceNumber | string | – | Elevator/boiler device number (mode=violations) |
ecbNumber | string | – | Associated ECB violation number (mode=violations) |
violationDateField | string | issueDate | Which violation date column dateFrom/dateTo/sorting apply to: issue date or disposition date (mode=violations) |
violationNumbers | array | – | Exact violation numbers to fetch (mode=violationsByNumber) |
sortAscending | boolean | false | Sort oldest-first instead of newest-first |
appToken | string | – | Optional free Socrata app token for higher rate limits |
maxItems | int | 20 | Hard cap on emitted records (1–10000) |
Example: permits issued in Manhattan for new buildings
{"mode": "permits","borough": "MANHATTAN","jobType": "NB","permitStatus": "ISSUED","maxItems": 100}
Example: permit history for a specific job number
{"mode": "permitsByJob","jobNumbers": ["340733647"]}
Example: active elevator violations in Queens, last 12 months
{"mode": "violations","borough": "QUEENS","violationCategory": "V-DOB VIOLATION - ACTIVE","violationTypeCode": "E","dateFrom": "2025-07-01","dateTo": "2026-07-01","maxItems": 200}
Example: self-certified corporate-owned permits in Brooklyn
{"mode": "permits","borough": "BROOKLYN","ownerBusinessType": "CORPORATION","selfCertifiedOnly": true,"maxItems": 100}
Example: violations at a specific address
{"mode": "violations","houseNumber": "222","streetName": "4TH AVE","borough": "MANHATTAN"}
Use cases
- Real estate due diligence — pull a property's full permit and violation history before acquisition
- Contractor / permittee research — track a licensed contractor's active and historical permits
- Compliance monitoring — watch for new violations by borough, category, or device type (elevators, boilers)
- Urban development analysis — study construction activity trends by borough, job type, or time period
- PropTech / data products — enrich property records with NYC DOB permit and violation history
FAQ
What is the data source? The NYC Department of Buildings' public datasets on NYC Open Data, served via the Socrata Open Data API (SODA): DOB Permit Issuance and DOB Violations.
How fresh is the data?
Both datasets are updated regularly by NYC DOB (the Permit Issuance dataset carries a dobRunDate field showing the last refresh date per record). This actor always queries the live dataset — there is no caching or staleness beyond NYC's own publishing schedule.
Is this affiliated with NYC or the Department of Buildings? No. This is an independent, third-party actor that queries NYC's public open-data API. It is not affiliated with or endorsed by the City of New York.
Why does borough sometimes not appear on a violation record?
The Violations dataset stores borough as a legacy internal code. The vast majority of rows use an unambiguous code (1–5, or M/Q/S), which is mapped to a readable borough name. A small number of legacy rows use an ambiguous code that cannot be reliably distinguished between Bronx and Brooklyn, or use garbage/blank values — those records simply omit the borough field rather than guess.
Why is bbl present on some violation records but not others?
DOB Violations doesn't include a Borough-Block-Lot (BBL) column directly, so this actor computes it from the row's borough, block, and lot when all three are present and valid (matching the same 10-digit BBL format the Permit Issuance dataset provides natively). Rows with a missing, ambiguous, or placeholder block/lot don't get a computed BBL.
Do I need a Socrata app token? No — the actor works fully without one. An optional free app token (get one at data.cityofnewyork.us/profile/app_tokens) raises the API's rate limit ceiling for very large runs, but isn't required for normal use.
What date format should I use for dateFrom/dateTo?
Always YYYY-MM-DD (e.g. 2025-01-31) regardless of which dataset/mode you're querying — the actor handles the underlying format differences between the two source datasets internally.
Can I look up a specific permit or violation by ID?
Yes — use mode=permitsByJob with jobNumbers, or mode=violationsByNumber with violationNumbers.
Does this cover ECB (Environmental Control Board) violations too? The DOB Violations dataset used here covers DOB-issued civil penalties. NYC also publishes a separate "DOB ECB Violations" dataset for summonses adjudicated by OATH/ECB, which is out of scope for this actor.