NYC Building Permits Scraper: DOB NOW Approved Permits
Pricing
from $2.10 / 1,000 permits
NYC Building Permits Scraper: DOB NOW Approved Permits
Get NYC DOB NOW approved building permits from NYC Open Data as clean records, one per permit: dates, borough, address, BIN/BBL, work types, job description, estimated cost, contractor and owner business. Filter by date, borough, work type, ZIP. Only-new-or-changed mode for daily feeds.
Pricing
from $2.10 / 1,000 permits
Rating
0.0
(0)
Developer
Michael Costa
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
What does NYC Building Permits Scraper do?
NYC Building Permits Scraper returns New York City building permits issued or approved through DOB NOW, as clean records: one per permit, with dates, address, BIN/BBL, work types, job description, estimated cost and the contractor's business. The data comes live from the Department of Buildings' official dataset on NYC Open Data (no login).
Schedule it with only new or changed permits switched on and every run returns just what DOB added or changed since the last one: a daily NYC construction-permit feed for your sheet, CRM or database.
Input fields · API · Use it from Claude, ChatGPT or Cursor (MCP)
Jump to: Fields · Price · How to use · Daily feed · Input · Output · AI agents (MCP) · Limits · FAQ
Try it in one click: the input comes pre-filled with General Construction permits issued in Brooklyn in the last 7 days. On 2026-10-04 that was 184 permits, about $0.55 (184 × $0.003, plus $0.00005 for the run start). Then pick your own boroughs, work types and dates.
What data does NYC Building Permits Scraper return?
| Field | Example | Notes |
|---|---|---|
id | B01441702-I1-GC/1/487381108 | Stable across runs: permit / sequence / tracking number |
workPermit | B01441702-I1-GC | DOB permit number; null for approved permits not yet issued |
filingReason | Initial Permit | Or a renewal (with or without changes), or No Work Permit |
permitStatus | Permit Issued | Or Signed-off (work completed) |
workTypes | ["General Construction"] | Every work type of the permit's job |
issuedDate, approvedDate, expiredDate | 2026-10-02 | YYYY-MM-DD |
address | 2565 FLATBUSH AVENUE, Brooklyn, NY 11234 | Also houseNumber, streetName, zipCode, borough |
bin, bbl | 3238574, 3084700050 | Building and tax-lot ids, to join with other NYC data |
jobDescription | Proposed alteration to an existing boat showroom, ... | As filed |
estimatedJobCost | 261000 | US dollars, the filer's estimate |
applicantBusinessName | SEASON BUILDERS CORP | With applicantLicenseNumber, permitteeLicenseType (GC, P, ...) |
ownerBusinessName | Marina at Kings Plaza LLC | Business names only, never people's names |
changeType | new | In only-new mode: new or changed; otherwise null |
sourceUrl | https://data.cityofnewyork.us/resource/rbx6-tga4.json?work_permit=... | The permit's source rows on NYC Open Data |
Plus jobFilingNumber, sequenceNumber, trackingNumber, workOnFloor, aptCondoNumbers, block, lot,
communityBoard, councilDistrict, censusTract, nta (neighborhood), latitude, longitude,
applicantBusinessAddress, filingRepresentativeBusinessName, sourceUpdatedAt and scrapedAt. The full list is
under Output.
How much does it cost to scrape NYC building permits?
You pay per permit: $3.00 per 1,000 permits, plus $0.00005 each time a run starts. Permits the source repeats, permits outside your filters, and (in only-new mode) permits DOB re-published without any change are never charged. A monitor run when the dataset hasn't changed returns nothing and costs only the start fee.
- The example above: 184 permits × $3.00/1,000 = $0.55.
- A month, for example: a daily only-new feed of Brooklyn General Construction permits, about 800 new or changed permits a month ≈ $2.40.
- Every permit DOB issued citywide in a week: about 3,100 permits ≈ $9.25 (raise Max results per run to 5,000 first).
- Caps: Max results per run in the input (1,000 unless you change it, so a run started with no input costs at most about $3), and Maximum cost per run in the run options. The run stops cleanly at whichever comes first.
How to scrape NYC building permits
- Open NYC Building Permits Scraper and click Try for free (or Start if you're signed in).
- Pick a date range: Last N days, or a From date and To date; choose whether they apply to the issued or the approved date.
- Pick Boroughs and Work types (empty = all), and any other filters: filing reason, status, ZIP codes, buildings (BIN), job-description words, minimum estimated cost.
- Click Start, then open the Output tab and export as JSON, CSV or Excel.
- For a daily feed, switch on Only new or changed permits since the last run, save the input as a task and schedule it.
Example: General Construction permits in Brooklyn this week
The pre-filled input:
{"lookbackDays": 7, "boroughs": ["Brooklyn"], "workTypes": ["General Construction"]}
It returned 184 permits (112 initial permits, 70 renewals, 2 "no work permit"; 55 of them on jobs with more than one work type), read from 804 source rows in 2.5 seconds. One of them (real output from a local run on 2026-10-04; the job description shortened):
{"id": "B01441702-I1-GC/1/487381108","workPermit": "B01441702-I1-GC","sequenceNumber": 1,"trackingNumber": "487381108","jobFilingNumber": "B01441702-I1","filingReason": "Initial Permit","permitStatus": "Permit Issued","workTypes": ["General Construction"],"jobDescription": "Proposed alteration to an existing boat showroom, including public and private toilet facilities, ...","estimatedJobCost": 261000.0,"issuedDate": "2026-10-02","approvedDate": "2026-09-15","expiredDate": "2026-10-22","borough": "Brooklyn","houseNumber": "2565","streetName": "FLATBUSH AVENUE","zipCode": "11234","address": "2565 FLATBUSH AVENUE, Brooklyn, NY 11234","workOnFloor": "Floor Number(s) 01 through 01","aptCondoNumbers": null,"bin": "3238574","bbl": "3084700050","block": "8470","lot": "50","communityBoard": 318,"councilDistrict": 46,"censusTract": "698","nta": "Marine Park-Mill Basin-Bergen Beach","latitude": 40.608035,"longitude": -73.920512,"permitteeLicenseType": "GC","applicantLicenseNumber": "621265","applicantBusinessName": "SEASON BUILDERS CORP","applicantBusinessAddress": "77 BOX STREET","filingRepresentativeBusinessName": null,"ownerBusinessName": "Marina at Kings Plaza LLC","changeType": null,"sourceUpdatedAt": "2026-10-03T18:42:11.170Z","sourceUrl": "https://data.cityofnewyork.us/resource/rbx6-tga4.json?work_permit=B01441702-I1-GC&sequence_number=1&tracking_number=487381108","scrapedAt": "2026-10-04T08:28:56.877917Z"}
Input
| Field | What it does |
|---|---|
Last N days (lookbackDays) | Permits from the last N days (default 7, up to 3,660), counted back from today in UTC. |
From date / To date (dateFrom, dateTo) | A fixed range, YYYY-MM-DD, inclusive; replaces Last N days. The dataset starts in June 2016. |
Date to filter on (dateField) | issued (default) or approved. Approved also finds permits not yet issued. |
| Boroughs | Manhattan, Bronx, Brooklyn, Queens, Staten Island. Empty = all. |
| Work types | Any of the 21 DOB NOW work types (General Construction, Plumbing, Full Demolition, Sidewalk Shed, Solar, ...). A permit matches if its job has one of them. Empty = all. |
| Filing reasons | Initial Permit, Renewal Permit Without Changes, Renewal Permit with Changes, No Work Permit. Empty = all. |
| Permit statuses | Permit Issued, Signed-off. Empty = both. |
| ZIP codes, Buildings (BIN) | Only these 5-digit ZIP codes or 7-digit BINs (up to 200 each). |
| Job description contains | Any of these words or phrases, not case sensitive (e.g. new building, hotel). |
| Minimum estimated job cost | In US dollars, as filed. |
Only new or changed permits (onlyNewOrChanged) | Return only what DOB added or changed since this search's last run. |
| Monitor name | Optional: gives a search its own memory. |
| Socrata app token | Optional: your own free token from NYC Open Data, for very large runs. |
| Max results per run | Caps the number of permits returned. Default 1,000; raise it for bigger runs. |
A daily feed of new Manhattan and Brooklyn demolition and new-building permits:
{"lookbackDays": 30,"boroughs": ["Manhattan", "Brooklyn"],"workTypes": ["Full Demolition", "General Construction"],"filingReasons": ["Initial Permit"],"keywords": ["new building", "demolition"],"onlyNewOrChanged": true}
Output
Every permit has the same fields; ones the source leaves empty are null. Output table columns: issued date, permit,
filing reason, status, work types, address, job description, estimated cost, applicant and owner business, change,
source link.
| Field | Type | Notes |
|---|---|---|
id | text | Permit number / sequence / tracking number. Permits without a permit number: unissued/<tracking number>/<BIN>. |
workPermit, jobFilingNumber | text or null | DOB's permit and job filing numbers. |
sequenceNumber | number or null | 1 for the first issuance, higher for renewals. |
trackingNumber | text or null | DOB's tracking number for this issuance. |
filingReason, permitStatus | text or null | As listed under Input. |
workTypes | list | Every work type of the job, sorted. |
jobDescription, workOnFloor, aptCondoNumbers | text or null | As filed. |
estimatedJobCost | number or null | US dollars, as filed (some filers enter placeholders such as 0.01). |
issuedDate, approvedDate, expiredDate | text or null | YYYY-MM-DD. |
borough, houseNumber, streetName, zipCode, address | text or null | Borough in one spelling; extra spaces removed. |
bin, bbl, block, lot, censusTract | text or null | Identifiers kept as text (no lost leading digits). |
communityBoard, councilDistrict | number or null | |
nta, latitude, longitude | text / number or null | Neighborhood (2020 NTA) and coordinates from the source. |
permitteeLicenseType, applicantLicenseNumber | text or null | DOB license type code and number of the applicant. |
applicantBusinessName, applicantBusinessAddress, filingRepresentativeBusinessName, ownerBusinessName | text or null | Businesses only. |
changeType | text or null | Only-new mode: new or changed. |
sourceUpdatedAt | text | When DOB last changed this permit's rows in the dataset (UTC). |
sourceUrl | text | NYC Open Data API query returning the permit's source rows. |
scrapedAt | text | When this run fetched it (UTC). |
The run's RUN_STATS record has the filters, the exact query sent, the dataset version it read (datasetUpdatedAt),
how many source rows and permits were read, filtered out, skipped as unchanged or duplicated, and any error.
Run it on a schedule, or from your own code
Save your input as a task with Only new or changed
permits on, and add it to a schedule: DOB updates the dataset once a
day (in the afternoon, New York time, on 2026-10-03), so a daily run in the evening or next morning is enough.
Collect the permits from the API
(GET https://api.apify.com/v2/actor-tasks/<task id>/runs/last/dataset/items?status=SUCCEEDED&format=csv, with your
API token), a webhook, or Google Sheets, Slack, Make, Zapier
and n8n through Apify's integrations.
Can I use NYC Building Permits Scraper from an AI agent (MCP)?
Yes, through Apify's MCP server, from Claude, ChatGPT, Cursor or any other MCP client. Add this to your client's MCP configuration; your client signs you in to Apify:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=humble-echidna/nyc-building-permits"}}}
To use an Apify API token instead of signing in, add
"headers": {"Authorization": "Bearer <APIFY_TOKEN>"} next to url.
An agent asking "which new buildings got permits in Queens this month?" can pass
{"boroughs": ["Queens"], "lookbackDays": 30, "filingReasons": ["Initial Permit"], "keywords": ["new building"], "maxResults": 50}Who it's for
Construction suppliers and subcontractors looking for jobs that just got permits, property-data and proptech developers who need NYC permits in their own database, real-estate researchers and analysts tracking construction activity by neighborhood. The recurring job: every day, the new permits matching a borough, trade or cost threshold, without re-downloading and re-cleaning the city's file.
Why this one?
- One record per permit. The source has a row per work type of the job, and repeats a few dozen permits; this joins them (3,710 source rows were 3,084 permits in the week to 2026-10-04), so you don't pay for or deduplicate the repeats.
- A real change feed. Only-new mode reads only rows DOB changed since your last run, labels permits
neworchanged(e.g. signed off, renewed), and skips the ones DOB re-published unchanged, free. A quiet day costs the $0.00005 start fee. - Ids that survive reloads. NYC Open Data's own row ids change every time DOB reloads a permit;
idhere is built from the permit's own numbers. - Clean fields. Borough in one spelling (the source mixes
BROOKLYNandBrooklyn), dates as dates, costs and coordinates as numbers, BIN and BBL as text, an address line, and a link to the source rows. - No people's names. Applicant, filing representative and owner names and owners' mailing addresses are left out on purpose; businesses and license numbers are included.
- Polite. It identifies itself honestly (User-Agent
HumbleEchidnaApify), follows the portal's robots.txt and its 1-second crawl delay, and backs off when the API asks it to.
Limits
- One dataset: DOB NOW: Build approved permits, which covers DOB NOW filings since 2016. It does not include electrical, elevator or Limited Alteration Application permits (NYC publishes those as separate datasets), older permits filed in DOB's BIS system, job filings that haven't been approved, or violations.
- No job type (NB, A1, DM, ...): this dataset doesn't carry it. Use work types, filing reasons and description keywords (e.g. "new building") instead.
- As fresh as the source: DOB updates the dataset once a day, roughly a day behind; nothing here is real time. Data quality is DOB's: some estimated costs are placeholders, some rows lack coordinates or a BBL.
- In only-new mode with Last N days, a permit changed after it falls out of the window isn't reported; use a
wider window or a fixed From date for a long-running feed. A monitor remembers up to 250,000 permits; one it
has forgotten comes back as
newif it changes. - 1,000 permits per run unless you raise Max results per run. A capped only-new run loses nothing: the next run continues from the oldest change it hasn't delivered.
- A run that overlaps DOB's daily load can read a few permits twice (returned once) or miss a few; in only-new mode the next run catches up.
FAQ
Is it legal to scrape NYC building permits?
The data is published by the NYC Department of Buildings on NYC Open Data, through an API documented for programs (SODA API for this dataset). NYC's Open Data Law says public data sets "shall be made available without any registration requirement, license requirement or restrictions on their use", provided the City may require a third party "to explicitly identify the source and version of the public data set, and a description of any modifications made to such public data set" (NYC Administrative Code § 23-502(d), Local Law 11 of 2012). NYC Open Data's own FAQ answers "Are there restrictions on how I can use Open Data?" with "Open Data belongs to all New Yorkers. There are no restrictions on the use of Open Data." (NYC Open Data FAQs). The portal's terms of use contain no clause against commercial reuse or automated access; the City gives no warranty for the data. No login is used.
Source and version: DOB NOW: Build – Approved Permits
(dataset rbx6-tga4, NYC Department of Buildings), as of the datasetUpdatedAt in each run's RUN_STATS and each
permit's sourceUpdatedAt. Modifications: rows of one permit joined (work types as a list), duplicates dropped,
borough spelling, whitespace and date formats normalized, numbers parsed, an address line and ids added, and person
names and owners' mailing addresses removed. Permits are public records; how you use contact details of the
businesses in them (for marketing, for example) is subject to the laws that apply to you.
Can I get only new or changed permits since my last run?
Yes: switch on Only new or changed permits since the last run. The first run returns every permit in your date
range; each later run returns only permits DOB added or changed since, with changeType new or changed, and
skips (without charging) permits DOB re-published with no change in any returned field. The memory is kept in your
own Apify account (key-value store nyc-building-permits-memory), one per set of filters; give a search a Monitor
name to keep it separate, or a new name to start over. It only remembers permits you actually received, so a run
cut short by your limits picks up where it stopped.
Why did my search return nothing, or fewer permits than expected?
DOB publishes once a day and about a day behind, so the last day or two may be empty, and weekends have few permits.
The log and the RUN_STATS record show the exact query, how many source rows came back and how many permits your
work-type filter left out. An only-new run returns nothing when DOB hasn't changed anything since your last run.
How is this different from downloading the data from NYC Open Data?
The data is free on NYC Open Data, and you can query the API yourself. This saves the work around it: joining the per-work-type rows into permits, stable ids, the cleaned fields, the filters in a form, and the memory that turns a daily run into a list of only what's new or changed, delivered where Apify integrations can send it.
Do I need a Socrata app token?
No. Without one, NYC Open Data throttles by IP address from a shared pool; a typical run makes a handful of requests. For very large runs (years of permits) you can add your own free token in Socrata app token; it is stored encrypted by Apify and sent only to NYC Open Data, in a request header.
Something that used to work now fails. Why?
The run log and the status say what went wrong, including NYC Open Data's own message when it refuses a query. If the city changed the dataset, please open an issue with the input you used.
Related actors
| Actor | Use it when |
|---|---|
| Dataset Transformer | You want to filter, rename or reshape the permits, or save them as CSV or Excel your way. |
| Join Datasets | You want to add your own data (e.g. your customer list by BIN or address) to each permit. |
Feedback and support
Found a bug, or need a field or filter that isn't here? Open an issue on the Issues tab with the input you used.
Versions
Current version: 0.1. See the Changelog tab for what changed in each version.