# NYC DOB Permits: Approved Permits with Contractor & Owner (`jserle/nyc-dob-permits-feed`) Actor

Daily feed of approved NYC Department of Buildings construction permits from DOB NOW: contractor (permittee) business, licence type and number, owner name and business, work type, address, BIN, block and lot, and approval, issue and expiry dates. Filter by date, borough, work type, ZIP, BIN.

- **URL**: https://apify.com/jserle/nyc-dob-permits-feed.md
- **Developed by:** [JS Tech Solutions](https://apify.com/jserle) (community)
- **Categories:** Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 permit records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## NYC DOB Permits: Approved Permits with Contractor & Owner

Pulls approved construction permits from the NYC Department of Buildings' DOB NOW system into clean JSON records: who the permit was issued to (the licensed contractor, with licence type and number, business name and address), who owns the building, what the work is (work type, floor, job description, estimated cost), where it is (address, borough, ZIP, BIN, block and lot, BBL, coordinates, community board, council district), and when it was approved, issued and expires. Filter by issue date, borough, work type, filing reason, status, ZIP, BIN, contractor or owner.

This is the City's own permit feed, published daily, not a scrape of the DOB NOW portal. On 2026-08-23 the dataset held 988,641 rows back to June 2016, with 14,892 permits issued in the previous 30 days and the newest issue date two days old.

### Who uses this data

- **Building-material, equipment and dumpster suppliers** calling the general contractor on every new permit in their delivery area the week it is issued.
- **Subcontractors** (plumbing, electrical, scaffold, demolition, roofing) finding GCs that just pulled permits for jobs that need their trade.
- **Construction lead-generation and data vendors** building NYC-wide lists of active contractors and owners, refreshed daily.
- **Insurers, surety and lien services** watching which contractors are active, where, and on what size of job.
- **Property investors, brokers and neighbours** tracking permits on a specific building (by BIN) or block.

### What you get

One dataset item per permit issuance per work type, newest issue date first. The City publishes a permit that covers several work types (a sidewalk shed that also covers a construction fence, say) as one row per work type with the same permit number; that grain is kept, so nothing is invented and nothing is merged. A real item, from `{"borough": "Brooklyn", "workType": "Plumbing"}`:

```json
{
  "jobFilingNumber": "B00925894-S3",
  "workPermit": "B00925894-S3-PL",
  "sequenceNumber": 1,
  "trackingNumber": "302783415",
  "filingReason": "Initial Permit",
  "permitStatus": "Permit Issued",
  "workType": "Plumbing",
  "workOnFloor": "Cellar",
  "jobDescription": "NO CHANGE IN USE, EGRESS OR OCCUPANCY. LEGALIZE CELLAR LAYOUT & COMPLY WITH BB 2011-010 ...",
  "estimatedJobCost": 100,
  "approvedDate": "2026-04-27",
  "issuedDate": "2026-08-21",
  "expiredDate": "2026-11-10",
  "houseNumber": "297",
  "streetName": "EAST 38 STREET",
  "borough": "Brooklyn",
  "zip": "11203",
  "bin": "3109635",
  "block": "4892",
  "lot": "45",
  "bbl": "3048920045",
  "communityBoard": "317",
  "councilDistrict": "40",
  "nta": "East Flatbush-Rugby",
  "latitude": 40.64992,
  "longitude": -73.941745,
  "permitteeLicenseType": "P",
  "permitteeLicenseNumber": "001253",
  "permitteeName": "ALAN P MITCHELL",
  "permitteeBusinessName": "A. M. PLUMBING COMPANY",
  "permitteeBusinessAddress": "37-32 10TH STREET",
  "filingRepresentativeName": "MERCEDES HERNANDEZ",
  "filingRepresentativeBusinessName": "S&M EXPEDITING",
  "ownerName": "Papa Diop",
  "ownerBusinessName": "Not Applicable",
  "ownerStreetAddress": null,
  "permitKey": "B00925894-S3-PL|1|Plumbing|302783415",
  "source": "https://data.cityofnewyork.us/resource/rbx6-tga4.json",
  "attribution": "NYC Department of Buildings (DOB) via NYC Open Data",
  "sourcePublishedAt": "2026-08-22T18:45:57.000Z",
  "fetchedAt": "2026-08-23T16:39:42.886Z"
}
```

Every record also carries `permitteeFirstName`, `permitteeLastName`, `aptCondoNumbers`, `censusTract`, `ownerCity`, `ownerState`, `ownerZip`, `sourceDataset`, `sourceDatasetTitle` and `datasetPage`. Field names are stable; a value the City did not publish is `null`, never a guess. Dates are ISO 8601 calendar dates. Boroughs are normalized to one spelling (the City publishes both `MANHATTAN` and `Manhattan`). `ownerBusinessName` is `Not Applicable` when the owner filed as an individual; that is the City's own value and is passed through. `permitKey` is the dedupe key (permit, sequence, work type, tracking number).

Licence types seen on the live data: `GC` general contractor (about 72% of rows), `P` plumber, `F` fire suppression, `S` sign hanger, `R` rigger, `PE`, `RA`, `O`, `PR`. Work types: General Construction, Plumbing, Sidewalk Shed, Mechanical Systems, Construction Fence, Structural, Sprinklers, Supported Scaffold, Sign, Foundation, Solar, Protection and Mechanical Methods, Suspended Scaffold, Earth Work, Standpipe, Boiler Equipment, Curb Cut, Antenna, Support of Excavation, Full Demolition, Green Roof.

### Input

Everything is optional. Run it with no input and you get the 100 newest permits issued in the last 7 days.

| Field | Type | Default | Notes |
| --- | --- | --- | --- |
| `issuedFrom` | ISO date | today minus 7 days | Permits issued on or after this date. Setting either date replaces the 7-day default. |
| `issuedTo` | ISO date | - | Permits issued on or before this date. |
| `borough` | enum | `any` | `Manhattan`, `Brooklyn`, `Queens`, `Bronx`, `Staten Island`. |
| `workType` | enum | `any` | One of the 21 work types listed above. |
| `filingReason` | enum | `any` | `Initial Permit`, `Renewal Permit Without Changes`, `Renewal Permit with Changes`, `No Work Permit`. |
| `permitStatus` | enum | `any` | `Permit Issued` or `Signed-off`. |
| `zip` | string | - | Five-digit ZIP of the job site. |
| `bin` | string | - | Seven-digit Building Identification Number; returns every permit on that building. |
| `permitteeBusinessContains` | string | - | Case-insensitive substring on the contractor's business name. |
| `ownerBusinessContains` | string | - | Case-insensitive substring on the owner's business name. |
| `maxResults` | integer | `100` | 1 to 50000. This is your cost cap: you pay per delivered record. |
| `includeRaw` | boolean | `false` | Attach a `raw` object with the source row under the City's column names. |

Every filter is applied by the City's server, so a narrow search is as fast as a broad one.

#### Example inputs

**New general-construction permits in Queens this week** (supplier or subcontractor prospecting):

```json
{ "borough": "Queens", "workType": "General Construction", "filingReason": "Initial Permit", "maxResults": 500 }
```

**Everything a contractor has pulled this year** (vetting, competitive intel):

```json
{ "issuedFrom": "2026-01-01", "permitteeBusinessContains": "safecon", "maxResults": 1000 }
```

**Permit history of one building**:

```json
{ "issuedFrom": "2016-01-01", "bin": "3109635", "maxResults": 200 }
```

### Pricing

**$0.003 per record; you pay only for records delivered.** One charge per dataset item, nothing else. Set `maxResults` and you have set your bill: 100 records is $0.30, a full month of roughly 15,000 permits is about $45. Filters are applied before delivery, and a search that matches nothing is free.

### Data source, refresh and terms

Records come from one Socrata (SODA) dataset published by the **NYC Department of Buildings (DOB)** on NYC Open Data: [DOB NOW: Build – Approved Permits](https://data.cityofnewyork.us/d/rbx6-tga4) (`rbx6-tga4`). The City describes it as "all approved construction permits in DOB NOW except for Electrical, Elevator, and Limited Alteration Application (LAA) which have their own datasets."

**Refresh:** the dataset's own metadata states Update Frequency **Daily**, Automation **Yes**. Read on 2026-08-23, it had been republished on 2026-08-22 and its newest issue date was 2026-08-21. Every record carries `sourcePublishedAt` (the City's publication timestamp) and `fetchedAt`.

**Terms:** the dataset's metadata carries no licence field. Use is governed by the [NYC Open Data Terms of Use](https://opendata.cityofnewyork.us/overview/#termsofuse), which state that "Public data sets made available on NYC Open Data are provided for informational purposes" and that by accessing them the user agrees to the Terms of Use and Privacy Policy of NYC.gov. The City does not warrant completeness or accuracy. Buyers are responsible for their own use of the data, including any outreach to the people named in it.

This Actor is **not affiliated with or endorsed by the NYC Department of Buildings or the City of New York**. Attribution on every record: `NYC Department of Buildings (DOB) via NYC Open Data`.

The Actor reads the public SODA endpoint with a descriptive User-Agent (`jserle-apify-actor/nyc-dob-permits-feed`), sends requests one at a time with the 1-second `Crawl-delay` from the host's robots.txt (which does not disallow `/resource/`), uses no app token, and caches nothing between runs. A default run makes four requests and finishes in a few seconds.

### Limitations

- **DOB NOW permits only.** Jobs still filed in the older BIS system are published separately as [DOB Permit Issuance](https://data.cityofnewyork.us/d/ipu4-2q9a) (`ipu4-2q9a`, about 3.99 million rows). That dataset is still refreshed but stores its dates as free text, so it is not read here. Electrical, elevator and LAA permits have their own DOB NOW datasets and are not included either.
- **No phone numbers.** The DOB NOW dataset publishes the contractor's licence and business address but not a phone number. The DOB licence number is the key to look one up.
- **No legacy "job type" code** (A1, A2, NB). DOB NOW publishes `filingReason`, `workType` and the job filing number (`-I1` initial, `-S1` subsequent filing) instead.
- **Renewals are separate rows.** A renewed permit appears again with a higher `sequenceNumber`; filter `filingReason` to `Initial Permit` to see each permit once.
- **A few hundred rows are unusable and are skipped, not delivered:** on 2026-08-23, 212 rows had no permit number, 308 carried the City's placeholder "Permit is not yet issued", and 306 had no issue date. The run summary reports how many were skipped.
- **A filter that matches nothing returns zero records and succeeds.** A run only fails when the source itself is broken, and then it exits non-zero having pushed and charged nothing: if the dataset shrinks implausibly, stops publishing a column the normalizer reads, returns fewer than 50 deliverable permits for the default 7-day window (NYC issues about 3,000 a week), skips more than one row in ten as malformed, or a page walk comes up short against the City's own row count. Large runs page by keyset (last issue date and row id), not by offset, so a permit the City adds or removes while a run is in progress cannot shift later pages and leave a hole in what you paid for.

### FAQ

#### How do I get NYC building permits issued this week with the contractor's name?

Run with no input. You get the 100 newest permits issued in the last 7 days, each with `permitteeName`, `permitteeBusinessName`, `permitteeLicenseNumber` and the owner. Raise `maxResults` to take the whole week (about 3,000 rows).

#### Can I search NYC DOB permits by address or building?

By building, yes: set `bin`. Every record carries house number, street, ZIP, block, lot and BBL, so matching on address downstream is straightforward. There is no free-text address filter because the City stores house numbers and street names in inconsistent formats.

#### How do I find new construction permits in Brooklyn for plumbing or sidewalk sheds?

Set `borough` and `workType`. Add `filingReason: "Initial Permit"` to exclude renewals.

#### Does it include permit status and expiry?

Yes: `permitStatus` (`Permit Issued` or `Signed-off`), `approvedDate`, `issuedDate` and `expiredDate`.

#### How often is NYC DOB permit data updated?

The City states daily. `sourcePublishedAt` on every record is the timestamp of the copy you received. Schedule the Actor daily with the default input to track the feed.

#### Is the contractor's phone number included?

No. DOB NOW publishes licence type, licence number, name, business name and business address.

### Related datasets

Other datasets by the same author, all pay-per-record with source, refresh cadence and terms stated on each listing:

**Public procurement and RFP feeds**

- [NYC PASSPort Procurement Scraper (RFPs, Bids & Contracts)](https://apify.com/jserle/nyc-passport-procurement)
- [E-Rate Form 470 RFP Scraper (USAC School & Library Bids)](https://apify.com/jserle/erate-form-470-rfp-feed)

**Nursing home and long-term care data**

- [New York Nursing Home Bed Availability (NYSDOH) Scraper](https://apify.com/jserle/ny-nursing-home-bed-census)
- [Nursing Home Deficiency Citations (CMS) Scraper](https://apify.com/jserle/nursing-home-deficiency-citations)
- [Nursing Home Fines & Civil Money Penalties (CMS) Scraper](https://apify.com/jserle/nursing-home-penalties-fines)
- [Nursing Home Directory & Ownership (CMS Form 671) Scraper](https://apify.com/jserle/ltc-facility-characteristics)
- [Nursing Home Daily Nurse Staffing (CMS PBJ) Scraper](https://apify.com/jserle/cms-nursing-home-staffing-daily)
- [Nursing Home Change of Ownership (CMS SNF CHOW) Scraper](https://apify.com/jserle/snf-change-of-ownership-tracker)

**Medicare provider enrollment data**

- [Medicare Revoked Providers List (CMS Revocations) Scraper](https://apify.com/jserle/medicare-revoked-providers)
- [Medicare Opt-Out Providers List (CMS Affidavits) Scraper](https://apify.com/jserle/medicare-opt-out-physicians)
- [Medicare Revalidation Due Date List (CMS) Scraper](https://apify.com/jserle/medicare-revalidation-due-leads)

**Developer and AI test data**

- [Synthetic Invoice OCR Ground Truth Dataset Generator](https://apify.com/jserle/ocr-ground-truth-document-factory)

# Actor input Schema

## `issuedFrom` (type: `string`):

ISO date, for example 2026-08-01. Permits issued on or after this date. If both dates are blank the window is the last 7 days.

## `issuedTo` (type: `string`):

ISO date, for example 2026-08-15. Permits issued on or before this date.

## `borough` (type: `string`):

One of the five boroughs, or any.

## `workType` (type: `string`):

The DOB NOW work type on the permit. One of the 21 types the City publishes, or any.

## `filingReason` (type: `string`):

Initial permits only, renewals only, or any. Renewals re-issue an existing permit and carry a higher sequence number.

## `permitStatus` (type: `string`):

Permit Issued (work may be in progress) or Signed-off (work complete), or any.

## `zip` (type: `string`):

Five-digit ZIP of the job site, for example 11201.

## `bin` (type: `string`):

Seven-digit NYC BIN of the job site, for example 1001389. Returns every permit on that building.

## `permitteeBusinessContains` (type: `string`):

Case-insensitive substring matched against the permittee's business name, for example: plumbing

## `ownerBusinessContains` (type: `string`):

Case-insensitive substring matched against the owner's business name, for example: housing authority

## `maxResults` (type: `integer`):

How many permit records to deliver, newest issue date first. You are charged per delivered record, so this is also your cost cap.

## `includeRaw` (type: `boolean`):

Attach a `raw` object with the Socrata row this record was built from, under the City's column names. Useful for auditing the normalization; roughly doubles item size.

## Actor input object example

```json
{
  "borough": "any",
  "workType": "any",
  "filingReason": "any",
  "permitStatus": "any",
  "maxResults": 100,
  "includeRaw": false
}
```

# Actor output Schema

## `results` (type: `string`):

One item per permit record delivered by this run, with contractor, owner, address and dates.

## `summary` (type: `string`):

Dataset health, publication date, rows matched and fetched, malformed rows skipped, delivered records, and whether the charge limit stopped the run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "borough": "any",
    "workType": "any",
    "filingReason": "any",
    "permitStatus": "any",
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("jserle/nyc-dob-permits-feed").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "borough": "any",
    "workType": "any",
    "filingReason": "any",
    "permitStatus": "any",
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("jserle/nyc-dob-permits-feed").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "borough": "any",
  "workType": "any",
  "filingReason": "any",
  "permitStatus": "any",
  "maxResults": 100
}' |
apify call jserle/nyc-dob-permits-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jserle/nyc-dob-permits-feed"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/cnnwcvRC8dtjYXcYp/builds/2OVEMNm4ayGQsoVyk/openapi.json
