NYC Building Permits Scraper: DOB NOW Approved Permits avatar

NYC Building Permits Scraper: DOB NOW Approved Permits

Pricing

from $2.10 / 1,000 permits

Go to Apify Store
NYC Building Permits Scraper: DOB NOW Approved 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

Michael Costa

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

8 days ago

Last modified

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?

FieldExampleNotes
idB01441702-I1-GC/1/487381108Stable across runs: permit / sequence / tracking number
workPermitB01441702-I1-GCDOB permit number; null for approved permits not yet issued
filingReasonInitial PermitOr a renewal (with or without changes), or No Work Permit
permitStatusPermit IssuedOr Signed-off (work completed)
workTypes["General Construction"]Every work type of the permit's job
issuedDate, approvedDate, expiredDate2026-10-02YYYY-MM-DD
address2565 FLATBUSH AVENUE, Brooklyn, NY 11234Also houseNumber, streetName, zipCode, borough
bin, bbl3238574, 3084700050Building and tax-lot ids, to join with other NYC data
jobDescriptionProposed alteration to an existing boat showroom, ...As filed
estimatedJobCost261000US dollars, the filer's estimate
applicantBusinessNameSEASON BUILDERS CORPWith applicantLicenseNumber, permitteeLicenseType (GC, P, ...)
ownerBusinessNameMarina at Kings Plaza LLCBusiness names only, never people's names
changeTypenewIn only-new mode: new or changed; otherwise null
sourceUrlhttps://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

  1. Open NYC Building Permits Scraper and click Try for free (or Start if you're signed in).
  2. 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.
  3. Pick Boroughs and Work types (empty = all), and any other filters: filing reason, status, ZIP codes, buildings (BIN), job-description words, minimum estimated cost.
  4. Click Start, then open the Output tab and export as JSON, CSV or Excel.
  5. 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

FieldWhat 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.
BoroughsManhattan, Bronx, Brooklyn, Queens, Staten Island. Empty = all.
Work typesAny 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 reasonsInitial Permit, Renewal Permit Without Changes, Renewal Permit with Changes, No Work Permit. Empty = all.
Permit statusesPermit 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 containsAny of these words or phrases, not case sensitive (e.g. new building, hotel).
Minimum estimated job costIn US dollars, as filed.
Only new or changed permits (onlyNewOrChanged)Return only what DOB added or changed since this search's last run.
Monitor nameOptional: gives a search its own memory.
Socrata app tokenOptional: your own free token from NYC Open Data, for very large runs.
Max results per runCaps 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.

FieldTypeNotes
idtextPermit number / sequence / tracking number. Permits without a permit number: unissued/<tracking number>/<BIN>.
workPermit, jobFilingNumbertext or nullDOB's permit and job filing numbers.
sequenceNumbernumber or null1 for the first issuance, higher for renewals.
trackingNumbertext or nullDOB's tracking number for this issuance.
filingReason, permitStatustext or nullAs listed under Input.
workTypeslistEvery work type of the job, sorted.
jobDescription, workOnFloor, aptCondoNumberstext or nullAs filed.
estimatedJobCostnumber or nullUS dollars, as filed (some filers enter placeholders such as 0.01).
issuedDate, approvedDate, expiredDatetext or nullYYYY-MM-DD.
borough, houseNumber, streetName, zipCode, addresstext or nullBorough in one spelling; extra spaces removed.
bin, bbl, block, lot, censusTracttext or nullIdentifiers kept as text (no lost leading digits).
communityBoard, councilDistrictnumber or null
nta, latitude, longitudetext / number or nullNeighborhood (2020 NTA) and coordinates from the source.
permitteeLicenseType, applicantLicenseNumbertext or nullDOB license type code and number of the applicant.
applicantBusinessName, applicantBusinessAddress, filingRepresentativeBusinessName, ownerBusinessNametext or nullBusinesses only.
changeTypetext or nullOnly-new mode: new or changed.
sourceUpdatedAttextWhen DOB last changed this permit's rows in the dataset (UTC).
sourceUrltextNYC Open Data API query returning the permit's source rows.
scrapedAttextWhen 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 new or changed (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; id here is built from the permit's own numbers.
  • Clean fields. Borough in one spelling (the source mixes BROOKLYN and Brooklyn), 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 new if 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

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.

ActorUse it when
Dataset TransformerYou want to filter, rename or reshape the permits, or save them as CSV or Excel your way.
Join DatasetsYou 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.