# NYC DOB Permits & Violations Scraper (`crawlerbros/nyc-dob-permits-violations-scraper`) Actor

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.

- **URL**: https://apify.com/crawlerbros/nyc-dob-permits-violations-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Real estate, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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 & Violations Scraper

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 computed `bbl` (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"`, `scrapedAt`
- `borough`, `houseNumber`, `streetName`, `address`, `bin`, `block`, `lot`, `bbl`
- `zipCode`, `communityBoard`, `councilDistrict`, `censusTract`, `ntaName`, `specialDistrict1`, `specialDistrict2`
- `jobNumber`, `jobDocNumber`, `jobType`, `permitType`, `permitSubtype`, `permitSequence`
- `permitStatus`, `filingStatus`, `workType`, `buildingType`
- `residential`, `selfCertified`, `ownerNonProfit` — booleans
- `siteFill`, `oilGas`
- `filingDate`, `issuanceDate`, `expirationDate`, `jobStartDate`, `dobRunDate` — `YYYY-MM-DD`
- `permitteeName`, `permitteeBusinessName`, `permitteePhone`, `permitteeLicenseType`, `permitteeLicenseNumber`, `hicLicense`
- `actAsSuperintendent`, `superintendentName`, `superintendentBusinessName`
- `siteSafetyManagerName`, `siteSafetyManagerBusinessName`
- `ownerBusinessType`, `ownerBusinessName`, `ownerName`, `ownerAddress`, `ownerCity`, `ownerState`, `ownerZipCode`
- `latitude`, `longitude`
- `permitSiNo`, `sourceUrl`

### Output: per violation (mode = `violations` / `violationsByNumber`)

- `recordType: "violation"`, `scrapedAt`
- `isn` — internal DOB BIS violation ID
- `borough`, `bin`, `block`, `lot`, `bbl` (derived — see FAQ)
- `houseNumber`, `street`, `address`
- `issueDate`, `dispositionDate` — `YYYY-MM-DD`
- `dispositionComments`
- `violationTypeCode`, `violationType`, `violationNumber`, `violationCategory`, `number`
- `deviceNumber`, `ecbNumber` (cross-reference to the DOB ECB Violations dataset — present on ~8% of records), `description`
- `sourceUrl`

### 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

```json
{
  "mode": "permits",
  "borough": "MANHATTAN",
  "jobType": "NB",
  "permitStatus": "ISSUED",
  "maxItems": 100
}
````

#### Example: permit history for a specific job number

```json
{
  "mode": "permitsByJob",
  "jobNumbers": ["340733647"]
}
```

#### Example: active elevator violations in Queens, last 12 months

```json
{
  "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

```json
{
  "mode": "permits",
  "borough": "BROOKLYN",
  "ownerBusinessType": "CORPORATION",
  "selfCertifiedOnly": true,
  "maxItems": 100
}
```

#### Example: violations at a specific address

```json
{
  "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](https://opendata.cityofnewyork.us/), served via the Socrata Open Data API (SODA): [DOB Permit Issuance](https://data.cityofnewyork.us/City-Government/DOB-Permit-Issuance/ipu4-2q9a) and [DOB Violations](https://data.cityofnewyork.us/Housing-Development/DOB-Violations/3h2n-5cm9).

**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](https://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.

# Actor input Schema

## `mode` (type: `string`):

What to fetch.

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

Filter to a single NYC borough (mode=permits / mode=violations).

## `houseNumber` (type: `string`):

Street/house number, e.g. `60` (mode=permits / mode=violations). Combine with `streetName` for an exact address lookup.

## `streetName` (type: `string`):

Street name as it appears in DOB records, e.g. `BAY 34 ST` (mode=permits / mode=violations). Case-insensitive.

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

NYC Building Identification Number, e.g. `3185434` (mode=permits / mode=violations).

## `block` (type: `string`):

Borough-Block-Lot (BBL) tax block number (mode=permits / mode=violations). Combine with `lot`.

## `lot` (type: `string`):

Borough-Block-Lot (BBL) tax lot number (mode=permits / mode=violations). Combine with `block`.

## `zipCode` (type: `string`):

Filter permits to a single 5-digit NYC ZIP code, e.g. `10013`.

## `jobType` (type: `string`):

Filter by DOB job type classification.

## `permitType` (type: `string`):

Filter by DOB permit type.

## `permitSubtype` (type: `string`):

Filter by the more specific permit subtype (subset of equipment-work / construction-equipment permit types).

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

Filter by the DOB-designated work type covered by the permit.

## `permitteeLicenseType` (type: `string`):

Filter by the professional license type of the person the permit was issued to.

## `ownerBusinessType` (type: `string`):

Filter by the property owner's business type.

## `selfCertifiedOnly` (type: `boolean`):

Only emit permits where the filing was self-certified by the applicant (no DOB plan review).

## `nonProfitOwnerOnly` (type: `boolean`):

Only emit permits where the property owner is flagged as a non-profit organization.

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

Filter by current permit status.

## `filingStatus` (type: `string`):

Filter by whether the permit filing was an initial filing or a renewal.

## `residentialOnly` (type: `boolean`):

Only emit permits flagged as residential work.

## `dateField` (type: `string`):

Which permit date column `dateFrom`/`dateTo`/sorting apply to.

## `dateFrom` (type: `string`):

Drop records before this date. For permits, applies to the field chosen in `dateField`; for violations, applies to the field chosen in `violationDateField`.

## `dateTo` (type: `string`):

Drop records after this date. For permits, applies to the field chosen in `dateField`; for violations, applies to the field chosen in `violationDateField`.

## `keyword` (type: `string`):

Full-text search. For permits, matches across permittee/owner names and other text fields (mode=permits). For violations, matches the violation description (mode=violations).

## `jobNumbers` (type: `array`):

DOB job numbers to fetch all permits for, e.g. `340733647`.

## `violationCategory` (type: `string`):

Filter by DOB violation category/status.

## `violationTypeCode` (type: `string`):

Filter by DOB violation type code (e.g. elevator, boiler, facade, construction).

## `deviceNumber` (type: `string`):

Filter to a specific equipment device number (elevators, boilers), e.g. `5P182`.

## `ecbNumber` (type: `string`):

Filter to violations linked to a specific Environmental Control Board (ECB) violation number, e.g. `34254160K`. Only ~8% of violations have an associated ECB number.

## `violationDateField` (type: `string`):

Which violation date column `dateFrom`/`dateTo`/sorting apply to.

## `violationNumbers` (type: `array`):

Exact violation numbers to fetch, e.g. `1391F/03`.

## `sortAscending` (type: `boolean`):

By default results are sorted newest-first by date. Enable to sort oldest-first instead.

## `appToken` (type: `string`):

Optional free Socrata app token to raise API rate limits. Get one at https://data.cityofnewyork.us/profile/app\_tokens. Not required - the actor works without it.

## `maxItems` (type: `integer`):

Hard cap on emitted records.

## Actor input object example

```json
{
  "mode": "permits",
  "borough": "MANHATTAN",
  "jobType": "",
  "permitType": "",
  "permitSubtype": "",
  "workType": "",
  "permitteeLicenseType": "",
  "ownerBusinessType": "",
  "selfCertifiedOnly": false,
  "nonProfitOwnerOnly": false,
  "permitStatus": "",
  "filingStatus": "",
  "residentialOnly": false,
  "dateField": "filingDate",
  "jobNumbers": [],
  "violationCategory": "",
  "violationTypeCode": "",
  "violationDateField": "issueDate",
  "violationNumbers": [],
  "sortAscending": false,
  "maxItems": 20
}
```

# Actor output Schema

## `records` (type: `string`):

Dataset containing all scraped DOB permit and violation records.

# 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 = {
    "mode": "permits",
    "borough": "MANHATTAN",
    "jobType": "",
    "permitType": "",
    "permitSubtype": "",
    "workType": "",
    "permitteeLicenseType": "",
    "ownerBusinessType": "",
    "selfCertifiedOnly": false,
    "nonProfitOwnerOnly": false,
    "permitStatus": "",
    "filingStatus": "",
    "residentialOnly": false,
    "dateField": "filingDate",
    "jobNumbers": [],
    "violationCategory": "",
    "violationTypeCode": "",
    "violationDateField": "issueDate",
    "violationNumbers": [],
    "sortAscending": false,
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/nyc-dob-permits-violations-scraper").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 = {
    "mode": "permits",
    "borough": "MANHATTAN",
    "jobType": "",
    "permitType": "",
    "permitSubtype": "",
    "workType": "",
    "permitteeLicenseType": "",
    "ownerBusinessType": "",
    "selfCertifiedOnly": False,
    "nonProfitOwnerOnly": False,
    "permitStatus": "",
    "filingStatus": "",
    "residentialOnly": False,
    "dateField": "filingDate",
    "jobNumbers": [],
    "violationCategory": "",
    "violationTypeCode": "",
    "violationDateField": "issueDate",
    "violationNumbers": [],
    "sortAscending": False,
    "maxItems": 20,
}

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

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

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

```

## CLI example

```bash
echo '{
  "mode": "permits",
  "borough": "MANHATTAN",
  "jobType": "",
  "permitType": "",
  "permitSubtype": "",
  "workType": "",
  "permitteeLicenseType": "",
  "ownerBusinessType": "",
  "selfCertifiedOnly": false,
  "nonProfitOwnerOnly": false,
  "permitStatus": "",
  "filingStatus": "",
  "residentialOnly": false,
  "dateField": "filingDate",
  "jobNumbers": [],
  "violationCategory": "",
  "violationTypeCode": "",
  "violationDateField": "issueDate",
  "violationNumbers": [],
  "sortAscending": false,
  "maxItems": 20
}' |
apify call crawlerbros/nyc-dob-permits-violations-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=crawlerbros/nyc-dob-permits-violations-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "NYC DOB Permits & Violations Scraper",
        "description": "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.",
        "version": "1.0",
        "x-build-id": "jzX0uM0n0bVgfcZKT"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/crawlerbros~nyc-dob-permits-violations-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-crawlerbros-nyc-dob-permits-violations-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/crawlerbros~nyc-dob-permits-violations-scraper/runs": {
            "post": {
                "operationId": "runs-sync-crawlerbros-nyc-dob-permits-violations-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/crawlerbros~nyc-dob-permits-violations-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-crawlerbros-nyc-dob-permits-violations-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "permits",
                            "permitsByJob",
                            "violations",
                            "violationsByNumber"
                        ],
                        "type": "string",
                        "description": "What to fetch.",
                        "default": "permits"
                    },
                    "borough": {
                        "title": "Borough",
                        "enum": [
                            "",
                            "MANHATTAN",
                            "BROOKLYN",
                            "QUEENS",
                            "BRONX",
                            "STATEN ISLAND"
                        ],
                        "type": "string",
                        "description": "Filter to a single NYC borough (mode=permits / mode=violations).",
                        "default": ""
                    },
                    "houseNumber": {
                        "title": "House number",
                        "type": "string",
                        "description": "Street/house number, e.g. `60` (mode=permits / mode=violations). Combine with `streetName` for an exact address lookup."
                    },
                    "streetName": {
                        "title": "Street name",
                        "type": "string",
                        "description": "Street name as it appears in DOB records, e.g. `BAY 34 ST` (mode=permits / mode=violations). Case-insensitive."
                    },
                    "bin": {
                        "title": "Building Identification Number (BIN)",
                        "type": "string",
                        "description": "NYC Building Identification Number, e.g. `3185434` (mode=permits / mode=violations)."
                    },
                    "block": {
                        "title": "Tax block",
                        "type": "string",
                        "description": "Borough-Block-Lot (BBL) tax block number (mode=permits / mode=violations). Combine with `lot`."
                    },
                    "lot": {
                        "title": "Tax lot",
                        "type": "string",
                        "description": "Borough-Block-Lot (BBL) tax lot number (mode=permits / mode=violations). Combine with `block`."
                    },
                    "zipCode": {
                        "title": "ZIP code (mode=permits)",
                        "type": "string",
                        "description": "Filter permits to a single 5-digit NYC ZIP code, e.g. `10013`."
                    },
                    "jobType": {
                        "title": "Job type (mode=permits)",
                        "enum": [
                            "",
                            "A1",
                            "A2",
                            "A3",
                            "DM",
                            "NB",
                            "SG"
                        ],
                        "type": "string",
                        "description": "Filter by DOB job type classification.",
                        "default": ""
                    },
                    "permitType": {
                        "title": "Permit type (mode=permits)",
                        "enum": [
                            "",
                            "AL",
                            "DM",
                            "EQ",
                            "EW",
                            "FO",
                            "NB",
                            "PL",
                            "SG"
                        ],
                        "type": "string",
                        "description": "Filter by DOB permit type.",
                        "default": ""
                    },
                    "permitSubtype": {
                        "title": "Permit subtype (mode=permits)",
                        "enum": [
                            "",
                            "BL",
                            "CH",
                            "EA",
                            "FA",
                            "FB",
                            "FN",
                            "FP",
                            "FS",
                            "MH",
                            "OT",
                            "SC",
                            "SD",
                            "SF",
                            "SH",
                            "SP"
                        ],
                        "type": "string",
                        "description": "Filter by the more specific permit subtype (subset of equipment-work / construction-equipment permit types).",
                        "default": ""
                    },
                    "workType": {
                        "title": "Work type (mode=permits)",
                        "enum": [
                            "",
                            "BL",
                            "CC",
                            "EQ",
                            "FA",
                            "FB",
                            "FP",
                            "FS",
                            "MH",
                            "NB",
                            "OT",
                            "PL",
                            "SD",
                            "SP"
                        ],
                        "type": "string",
                        "description": "Filter by the DOB-designated work type covered by the permit.",
                        "default": ""
                    },
                    "permitteeLicenseType": {
                        "title": "Permittee license type (mode=permits)",
                        "enum": [
                            "",
                            "DM",
                            "FS",
                            "GC",
                            "HI",
                            "MP",
                            "NW",
                            "OB",
                            "OW",
                            "PE",
                            "RA",
                            "SI"
                        ],
                        "type": "string",
                        "description": "Filter by the professional license type of the person the permit was issued to.",
                        "default": ""
                    },
                    "ownerBusinessType": {
                        "title": "Owner business type (mode=permits)",
                        "enum": [
                            "",
                            "CORPORATION",
                            "INDIVIDUAL",
                            "PARTNERSHIP",
                            "CONDO/CO-OP",
                            "OTHER",
                            "OTHER GOV'T AGENCY",
                            "NYCHA/HHC",
                            "NYC AGENCY",
                            "NYCHA",
                            "HPD",
                            "HHC",
                            "DCAS",
                            "NY STATE",
                            "DOE"
                        ],
                        "type": "string",
                        "description": "Filter by the property owner's business type.",
                        "default": ""
                    },
                    "selfCertifiedOnly": {
                        "title": "Self-certified only (mode=permits)",
                        "type": "boolean",
                        "description": "Only emit permits where the filing was self-certified by the applicant (no DOB plan review).",
                        "default": false
                    },
                    "nonProfitOwnerOnly": {
                        "title": "Non-profit owner only (mode=permits)",
                        "type": "boolean",
                        "description": "Only emit permits where the property owner is flagged as a non-profit organization.",
                        "default": false
                    },
                    "permitStatus": {
                        "title": "Permit status (mode=permits)",
                        "enum": [
                            "",
                            "IN PROCESS",
                            "ISSUED",
                            "RE-ISSUED",
                            "REVOKED"
                        ],
                        "type": "string",
                        "description": "Filter by current permit status.",
                        "default": ""
                    },
                    "filingStatus": {
                        "title": "Filing status (mode=permits)",
                        "enum": [
                            "",
                            "INITIAL",
                            "RENEWAL"
                        ],
                        "type": "string",
                        "description": "Filter by whether the permit filing was an initial filing or a renewal.",
                        "default": ""
                    },
                    "residentialOnly": {
                        "title": "Residential only (mode=permits)",
                        "type": "boolean",
                        "description": "Only emit permits flagged as residential work.",
                        "default": false
                    },
                    "dateField": {
                        "title": "Date field to filter/sort by (mode=permits)",
                        "enum": [
                            "filingDate",
                            "issuanceDate",
                            "expirationDate",
                            "jobStartDate"
                        ],
                        "type": "string",
                        "description": "Which permit date column `dateFrom`/`dateTo`/sorting apply to.",
                        "default": "filingDate"
                    },
                    "dateFrom": {
                        "title": "Date from (YYYY-MM-DD)",
                        "type": "string",
                        "description": "Drop records before this date. For permits, applies to the field chosen in `dateField`; for violations, applies to the field chosen in `violationDateField`."
                    },
                    "dateTo": {
                        "title": "Date to (YYYY-MM-DD)",
                        "type": "string",
                        "description": "Drop records after this date. For permits, applies to the field chosen in `dateField`; for violations, applies to the field chosen in `violationDateField`."
                    },
                    "keyword": {
                        "title": "Keyword search",
                        "type": "string",
                        "description": "Full-text search. For permits, matches across permittee/owner names and other text fields (mode=permits). For violations, matches the violation description (mode=violations)."
                    },
                    "jobNumbers": {
                        "title": "Job numbers (mode=permitsByJob)",
                        "type": "array",
                        "description": "DOB job numbers to fetch all permits for, e.g. `340733647`.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "violationCategory": {
                        "title": "Violation category (mode=violations)",
                        "enum": [
                            "",
                            "V-DOB VIOLATION - ACTIVE",
                            "V*-DOB VIOLATION - DISMISSED",
                            "V*-DOB VIOLATION - Resolved",
                            "V%-DOB VIOLATION",
                            "V%*-DOB VIOLATION - DISMISSED",
                            "VW-VIOLATION WORK WITHOUT PERMIT - ACTIVE",
                            "VW*-VIOLATION - WORK W/O PERMIT DISMISSED",
                            "VP-VIOLATION UNSERVED ECB-ACTIVE",
                            "VP*-VIOLATION UNSERVED ECB- DISMISSED",
                            "VPW-VIOLATION UNSERVED ECB-WORK WITHOUT PERMIT-ACTIVE",
                            "VPW*-VIOLATION UNSERVED ECB-WORK WITHOUT PERMIT-DISMISSED",
                            "VH-VIOLATION HAZARDOUS - ACTIVE",
                            "VH*-VIOLATION HAZARDOUS DISMISSED",
                            "VWH-VIOLATION WORK W/OUT PMT HAZARDOUS - ACTIVE",
                            "VWH*-VIOLATION WORK W/OUT PMT HAZARDOUS DISMISSED"
                        ],
                        "type": "string",
                        "description": "Filter by DOB violation category/status.",
                        "default": ""
                    },
                    "violationTypeCode": {
                        "title": "Violation type code (mode=violations)",
                        "enum": [
                            "",
                            "7A",
                            "7S",
                            "A",
                            "ACC1",
                            "ACH1",
                            "ACJ1",
                            "AEUHAZ1",
                            "B",
                            "BENCH",
                            "C",
                            "CLOS",
                            "CMQ",
                            "COMPBLD",
                            "CS",
                            "E",
                            "EARCX",
                            "EB",
                            "EGNCY",
                            "EGRADE",
                            "ES",
                            "EVCAT1",
                            "EVCAT5",
                            "FISP",
                            "FISPFCS",
                            "FISPHAZ",
                            "FISPNRF",
                            "HBLVIO",
                            "HVCAT5",
                            "HVIOS",
                            "IMD",
                            "IMEGNCY",
                            "JVCAT5",
                            "JVIOS",
                            "L1198",
                            "LANDMK",
                            "LANDMRK",
                            "LBLVIO",
                            "LL10/80",
                            "LL10/81",
                            "LL1080",
                            "LL1081",
                            "LL11/98",
                            "LL1198",
                            "LL16",
                            "LL2604",
                            "LL2604E",
                            "LL2604S",
                            "LL41",
                            "LL5",
                            "LL6291",
                            "P",
                            "PA",
                            "RWNRF",
                            "UB",
                            "UB*",
                            "V*",
                            "VCAT1",
                            "Z"
                        ],
                        "type": "string",
                        "description": "Filter by DOB violation type code (e.g. elevator, boiler, facade, construction).",
                        "default": ""
                    },
                    "deviceNumber": {
                        "title": "Device number (mode=violations)",
                        "type": "string",
                        "description": "Filter to a specific equipment device number (elevators, boilers), e.g. `5P182`."
                    },
                    "ecbNumber": {
                        "title": "ECB number (mode=violations)",
                        "type": "string",
                        "description": "Filter to violations linked to a specific Environmental Control Board (ECB) violation number, e.g. `34254160K`. Only ~8% of violations have an associated ECB number."
                    },
                    "violationDateField": {
                        "title": "Violation date field to filter/sort by (mode=violations)",
                        "enum": [
                            "issueDate",
                            "dispositionDate"
                        ],
                        "type": "string",
                        "description": "Which violation date column `dateFrom`/`dateTo`/sorting apply to.",
                        "default": "issueDate"
                    },
                    "violationNumbers": {
                        "title": "Violation numbers (mode=violationsByNumber)",
                        "type": "array",
                        "description": "Exact violation numbers to fetch, e.g. `1391F/03`.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "sortAscending": {
                        "title": "Sort ascending (oldest first)",
                        "type": "boolean",
                        "description": "By default results are sorted newest-first by date. Enable to sort oldest-first instead.",
                        "default": false
                    },
                    "appToken": {
                        "title": "Socrata app token (optional)",
                        "type": "string",
                        "description": "Optional free Socrata app token to raise API rate limits. Get one at https://data.cityofnewyork.us/profile/app_tokens. Not required - the actor works without it."
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Hard cap on emitted records.",
                        "default": 20
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
