# NYC DOB NOW Building Permits Scraper (`automation-lab/nyc-dob-now-building-permits-scraper`) Actor

🏗️ Search official NYC DOB NOW approved permits and export project, contractor, owner, location, cost, and status data for construction leads and market intelligence.

- **URL**: https://apify.com/automation-lab/nyc-dob-now-building-permits-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event + usage

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 NOW Building Permits Scraper

Turn official New York City building permits into fresh construction leads and market intelligence.

The **NYC DOB NOW Building Permits Scraper** searches the official DOB NOW: Build – Approved Permits dataset and exports clean permit, project, applicant, contractor, owner, address, cost, and location data.

Use it for daily territory monitoring, contractor prospecting, project research, underwriting signals, supplier outreach, and construction analytics.

No NYC account, browser, proxy, cookies, or API token is required.

### What does NYC DOB NOW Building Permits Scraper do?

This Actor queries NYC Open Data's official approved-permits dataset.

It can:

- 📅 find newly issued permits in a date range;
- 🗺️ focus on one or more boroughs or ZIP codes;
- 🏗️ filter by trade, permit status, or filing reason;
- 💰 select projects by estimated job cost;
- 👷 search applicant names, businesses, and license numbers;
- 🏢 search owner names and owner businesses;
- 📍 export coordinates and administrative geographies;
- 🔄 support scheduled permit monitoring;
- 📦 deliver JSON, CSV, Excel, XML, RSS, or API output through Apify datasets.

Every result represents one approved DOB NOW work permit.

### Who is this NYC permit scraper for?

#### Contractors and subcontractors

Monitor projects in your boroughs and trades before competitors find them.

#### Building-material suppliers

Identify recently permitted work that may need equipment, fixtures, finishes, or materials.

#### Insurers and lenders

Use permit activity, scope, ownership, and project value as underwriting or monitoring signals.

#### Developers and brokers

Track construction activity by owner, neighborhood, work type, and estimated cost.

#### Construction-intelligence teams

Feed normalized official permit records into CRM, BI, warehouse, or lead-scoring systems.

#### Researchers and journalists

Analyze where NYC construction is occurring and who is responsible for permitted work.

### Why use this Actor?

NYC Open Data is authoritative, but operational lead workflows require repeatable filters, normalized types, pagination, exports, and scheduling.

This Actor handles those details for you.

Benefits include:

- official public source data;
- no screen scraping or browser overhead;
- server-side filtering for efficient runs;
- numbers emitted as numbers;
- dates emitted as ISO timestamps;
- stable field names for automation;
- source links and query provenance on every row;
- automatic bounded retries for temporary API errors;
- pay-per-event billing tied to delivered records.

### What NYC permit data can I extract?

| Group | Example fields |
|---|---|
| Permit identity | job filing number, work permit, sequence, tracking number |
| Status | permit status, filing reason |
| Dates | approved date, issued date, expiry date |
| Site | house number, street, full address, borough, ZIP |
| Property | block, lot, BIN, BBL |
| Work | work type, floor, apartment/condo, job description |
| Value | estimated job cost |
| Applicant | name, business, license, license type, address |
| Owner | name, business, street, city, state, ZIP |
| Geography | community board, council district, census tract, NTA |
| Coordinates | latitude, longitude |
| Provenance | applied query, dataset ID, source URL, retrieval time |

Blank source values are omitted rather than converted into misleading empty strings.

### How to scrape NYC building permits

1. Open the Actor input page.
2. Choose an issue-date range or keep the rolling 30-day default.
3. Add borough, ZIP, work type, status, or filing-reason filters.
4. Optionally add project-value, applicant, or owner filters.
5. Set a small `maxItems` for a first run.
6. Click **Start**.
7. Review results in the **Dataset** tab.
8. Export them or connect the dataset to your workflow.

Start broad, inspect the source values returned, then reuse exact values in narrower filters.

### Input options

#### Permit dates

- `issuedFrom`: first issue date, formatted `YYYY-MM-DD`.
- `issuedTo`: last issue date, formatted `YYYY-MM-DD`.
- `approvedFrom`: optional first approval date.
- `approvedTo`: optional last approval date.

If issue dates are blank, the Actor searches the most recent 30 days through today.

#### Territory

- `boroughs`: exact borough names such as `MANHATTAN`, `BROOKLYN`, or `QUEENS`.
- `zipCodes`: one or more site ZIP codes.

#### Permit and work

- `workTypes`: exact official work-type values.
- `permitStatuses`: exact official permit statuses.
- `filingReasons`: exact official filing reasons.

#### Lead filters

- `applicantQuery`: searches applicant name, business, license number, and related applicant fields.
- `ownerQuery`: searches owner name and owner business.
- `minEstimatedCost`: minimum project estimate.
- `maxEstimatedCost`: maximum project estimate.

#### Run limit

- `maxItems`: maximum records saved, from 1 to 50,000.

All filter groups are combined with AND.

Values inside one list are combined as alternatives.

### Input example

```json
{
  "issuedFrom": "2026-07-01",
  "issuedTo": "2026-07-31",
  "boroughs": ["BROOKLYN", "QUEENS"],
  "minEstimatedCost": 250000,
  "maxItems": 100
}
````

This finds recently issued, higher-value projects in Brooklyn or Queens.

### Output example

```json
{
  "jobFilingNumber": "B01234567-I1",
  "workPermit": "B01234567-I1-GC",
  "filingReason": "Initial",
  "permitStatus": "ISSUED",
  "issuedDate": "2026-07-16T00:00:00.000Z",
  "address": "123 EXAMPLE STREET",
  "borough": "BROOKLYN",
  "zipCode": "11201",
  "workType": "General Construction",
  "estimatedJobCost": 750000,
  "applicantName": "JANE CONTRACTOR",
  "applicantBusinessName": "EXAMPLE BUILDERS LLC",
  "ownerName": "SAMPLE OWNER",
  "latitude": 40.693,
  "longitude": -73.99,
  "sourceDatasetId": "rbx6-tga4",
  "sourceUrl": "https://data.cityofnewyork.us/resource/rbx6-tga4.json?...",
  "retrievedAt": "2026-07-19T12:00:00.000Z"
}
```

The example illustrates the shape; actual values come directly from NYC Open Data.

### How much does it cost to scrape NYC building permits?

This Actor uses pay-per-event pricing.

You pay a small run-start charge plus a charge for each permit record saved.

Your Apify plan determines the applicable price tier.

Higher tiers receive lower per-record prices.

| Plan tier | Price per permit record |
|---|---:|
| Free | $0.000039882 |
| Bronze | $0.00003468 |
| Silver | $0.00002705 |
| Gold | $0.000020808 |
| Platinum | $0.000013872 |
| Diamond | $0.00001 |

Every run also has a $0.005 start event. At the Bronze tier, 1,000 permit records cost about $0.040 including the start event.

Before a large export:

- run 10–25 records;
- review the output fields;
- verify your filters;
- estimate the full result count;
- increase `maxItems` only when ready.

The Actor uses an HTTP API rather than a browser or paid proxy, keeping compute costs low.

### Daily NYC permit lead monitoring

A strong recurring workflow is:

1. save an input for your territory and trade;
2. schedule it daily in Apify;
3. use a narrow rolling issue-date window;
4. export results to a named dataset or integration;
5. deduplicate on `jobFilingNumber`, `workPermit`, `sequenceNumber`, and `workType`;
6. score leads using estimated cost, work type, and owner or applicant attributes.

For multiple sales territories, create separate tasks with different borough or ZIP filters.

### Contractor and applicant research

Use `applicantQuery` to search:

- first, middle, or last name;
- applicant business name;
- applicant license number.

The match is case-insensitive and runs against the official source fields.

For a company-focused workflow, search a distinctive business-name fragment.

For license monitoring, provide the complete license number when available.

### Owner and developer research

Use `ownerQuery` to search both owner name and owner business name.

Returned owner attributes can include street address, city, state, and ZIP.

Possible workflows include:

- tracking a developer's active construction pipeline;
- finding repeat property owners;
- monitoring work by portfolio or lender territory;
- joining permits to internal account records;
- identifying projects for outreach.

Always verify current contact details independently before outreach.

### Borough, ZIP, and trade segmentation

Borough filters are useful for territory assignment.

ZIP filters provide more granular routing.

Work-type filters can separate general construction, plumbing, mechanical, structural, and other official categories.

For reliable matches, copy exact source values from a broad sample run.

Do not guess punctuation or abbreviations when an exact value is available.

### Integrations

#### Google Sheets

Send new permit rows to a shared prospecting sheet.

#### Airtable

Create a permit table linked to owners, contractors, and sales territories.

#### Zapier or Make

Trigger CRM creation or notifications when a high-value project appears.

#### Slack or email

Send daily summaries for specific boroughs, ZIPs, trades, or owners.

#### Data warehouses

Load the dataset into BigQuery, Snowflake, Redshift, or PostgreSQL for longitudinal analysis.

#### Webhooks

Trigger a downstream service when the Actor run finishes.

### API access with cURL

```bash
curl "https://api.apify.com/v2/acts/automation-lab~nyc-dob-now-building-permits-scraper/runs?token=$APIFY_TOKEN" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"boroughs":["MANHATTAN"],"maxItems":25}'
```

Store tokens in environment variables, not source code.

### API access with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/nyc-dob-now-building-permits-scraper').call({
  boroughs: ['BROOKLYN'],
  minEstimatedCost: 500000,
  maxItems: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Use the dataset ID from the completed run.

### API access with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/nyc-dob-now-building-permits-scraper').call(
    run_input={
        'boroughs': ['QUEENS'],
        'maxItems': 50,
    }
)
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

The Python client can also start runs asynchronously.

### Use with Apify MCP

Connect AI assistants through:

`https://mcp.apify.com/?tools=automation-lab/nyc-dob-now-building-permits-scraper`

Example prompts:

- “Find 25 recently issued Manhattan building permits.”
- “Extract high-value Brooklyn and Queens construction permits.”
- “Monitor permits associated with this applicant business.”
- “Summarize work types and estimated costs in the returned dataset.”

#### Claude Code setup

```bash
claude mcp add --transport http apify https://mcp.apify.com/?tools=automation-lab/nyc-dob-now-building-permits-scraper
```

#### Claude Desktop setup

Add this server configuration to Claude Desktop:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=automation-lab/nyc-dob-now-building-permits-scraper"
    }
  }
}
```

#### Cursor setup

Add the same `mcpServers` JSON to Cursor's MCP settings.

#### VS Code setup

Add the Apify HTTP MCP URL in VS Code's MCP server settings, then select this Actor tool.

### Tips for reliable results

- Use strict `YYYY-MM-DD` dates.
- Keep `issuedFrom` before or equal to `issuedTo`.
- Copy exact borough, status, reason, and work-type values from source output.
- Start with a low `maxItems`.
- Use narrower date windows for scheduled monitors.
- Combine borough and value filters for sales territories.
- Deduplicate across scheduled runs using permit identity fields.
- Keep source URLs for auditability.
- Expect optional fields to vary by permit.

### Troubleshooting

#### Why did my run return no permits?

The selected filters may have no intersection.

Remove filters one group at a time, broaden the dates, and try again.

Check spelling against a broad sample run.

#### Why was my date rejected?

Dates must use `YYYY-MM-DD` and the start cannot be later than the end.

#### Why is a field missing from one row?

NYC records do not populate every optional field for every filing.

The Actor omits empty values.

#### Why is my applicant search too broad?

Use a longer company fragment or a full license number.

### Data source and coverage

The source is NYC Open Data dataset `rbx6-tga4`, **DOB NOW: Build – Approved Permits**.

The Actor covers that dataset only.

It does not claim to combine:

- DOB NOW Electrical permits;
- Elevator records;
- Limited Alteration Application records;
- legacy BIS permits;
- private phone or email enrichment;
- property ownership enrichment from third-party sources.

This explicit scope keeps the product reliable and understandable.

### Is scraping NYC building permit data legal?

The Actor accesses a public government open-data API without login or circumvention.

Public availability does not remove every legal or compliance obligation.

You are responsible for your use of the data, including outreach, privacy, licensing, retention, and sector-specific rules.

Do not use the output for harassment, discrimination, or unlawful decisions.

Consult qualified counsel for your use case when necessary.

### FAQ

#### Does the Actor need a proxy?

No. It uses the anonymous official NYC Open Data API.

#### Does it need an NYC account?

No.

#### Can I schedule daily runs?

Yes. Save the input as an Apify task and add a schedule.

#### Can I export CSV or Excel?

Yes. Apify datasets support CSV, Excel, JSON, XML, RSS, and API access.

#### Can I search by contractor?

Use `applicantQuery` for applicant names, businesses, and licenses.

#### Can I search by owner?

Yes, with `ownerQuery`.

#### Are costs numeric?

Yes. Valid estimated job costs are emitted as JSON numbers.

#### Are dates normalized?

Yes. Source dates are emitted as ISO timestamps.

#### How many records can one run save?

Up to 50,000, controlled by `maxItems`.

#### Does it enrich emails or phone numbers?

No. It preserves official permit fields only.

### Related scrapers

Combine this Actor with other automation-lab tools when your workflow needs additional public construction or business intelligence.

Browse the automation-lab profile:

`https://apify.com/automation-lab`

A common portfolio workflow is to combine permit monitoring with official business registries, property records, or contact-validation Actors while preserving source lineage.

### Build a repeatable NYC construction data pipeline

Start with a 25-record run.

Validate the fields and exact source values.

Save your input as a task.

Schedule the task for the cadence your team needs.

Connect the output dataset to CRM, spreadsheets, alerts, or analytics.

The result is a focused, auditable pipeline for newly approved NYC construction work.

# Actor input Schema

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

YYYY-MM-DD. Defaults to 30 days ago.

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

YYYY-MM-DD. Defaults to today.

## `approvedFrom` (type: `string`):

Optional approval-date lower bound in YYYY-MM-DD format.

## `approvedTo` (type: `string`):

Optional approval-date upper bound in YYYY-MM-DD format.

## `boroughs` (type: `array`):

Exact official borough names, such as MANHATTAN or BROOKLYN.

## `zipCodes` (type: `array`):

Keep permit sites in these ZIP codes.

## `workTypes` (type: `array`):

Exact official work types, such as General Construction or Plumbing.

## `permitStatuses` (type: `array`):

Exact official permit statuses. Leave empty for all statuses.

## `filingReasons` (type: `array`):

Exact official filing reasons, such as Initial or Renewal.

## `applicantQuery` (type: `string`):

Case-insensitive search across applicant names, business name, and license number.

## `ownerQuery` (type: `string`):

Case-insensitive search across owner name and owner business.

## `minEstimatedCost` (type: `number`):

Keep projects at or above this estimated USD cost.

## `maxEstimatedCost` (type: `number`):

Keep projects at or below this estimated USD cost.

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

Stop after saving this many permits. Keep the first run small.

## Actor input object example

```json
{
  "boroughs": [
    "MANHATTAN"
  ],
  "maxItems": 20
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "boroughs": [
        "MANHATTAN"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/nyc-dob-now-building-permits-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 = {
    "boroughs": ["MANHATTAN"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/nyc-dob-now-building-permits-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 '{
  "boroughs": [
    "MANHATTAN"
  ],
  "maxItems": 20
}' |
apify call automation-lab/nyc-dob-now-building-permits-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "NYC DOB NOW Building Permits Scraper",
        "description": "🏗️ Search official NYC DOB NOW approved permits and export project, contractor, owner, location, cost, and status data for construction leads and market intelligence.",
        "version": "0.1",
        "x-build-id": "LejxULVMz1o0iAkYy"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/automation-lab~nyc-dob-now-building-permits-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-automation-lab-nyc-dob-now-building-permits-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/automation-lab~nyc-dob-now-building-permits-scraper/runs": {
            "post": {
                "operationId": "runs-sync-automation-lab-nyc-dob-now-building-permits-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/automation-lab~nyc-dob-now-building-permits-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-automation-lab-nyc-dob-now-building-permits-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",
                "properties": {
                    "issuedFrom": {
                        "title": "Issued on or after",
                        "type": "string",
                        "description": "YYYY-MM-DD. Defaults to 30 days ago."
                    },
                    "issuedTo": {
                        "title": "Issued on or before",
                        "type": "string",
                        "description": "YYYY-MM-DD. Defaults to today."
                    },
                    "approvedFrom": {
                        "title": "Approved on or after",
                        "type": "string",
                        "description": "Optional approval-date lower bound in YYYY-MM-DD format."
                    },
                    "approvedTo": {
                        "title": "Approved on or before",
                        "type": "string",
                        "description": "Optional approval-date upper bound in YYYY-MM-DD format."
                    },
                    "boroughs": {
                        "title": "Boroughs",
                        "type": "array",
                        "description": "Exact official borough names, such as MANHATTAN or BROOKLYN.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "zipCodes": {
                        "title": "Site ZIP codes",
                        "type": "array",
                        "description": "Keep permit sites in these ZIP codes.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "workTypes": {
                        "title": "Work types",
                        "type": "array",
                        "description": "Exact official work types, such as General Construction or Plumbing.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "permitStatuses": {
                        "title": "Permit statuses",
                        "type": "array",
                        "description": "Exact official permit statuses. Leave empty for all statuses.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "filingReasons": {
                        "title": "Filing reasons",
                        "type": "array",
                        "description": "Exact official filing reasons, such as Initial or Renewal.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "applicantQuery": {
                        "title": "Applicant or contractor contains",
                        "type": "string",
                        "description": "Case-insensitive search across applicant names, business name, and license number."
                    },
                    "ownerQuery": {
                        "title": "Owner contains",
                        "type": "string",
                        "description": "Case-insensitive search across owner name and owner business."
                    },
                    "minEstimatedCost": {
                        "title": "Minimum estimated job cost",
                        "minimum": 0,
                        "type": "number",
                        "description": "Keep projects at or above this estimated USD cost."
                    },
                    "maxEstimatedCost": {
                        "title": "Maximum estimated job cost",
                        "minimum": 0,
                        "type": "number",
                        "description": "Keep projects at or below this estimated USD cost."
                    },
                    "maxItems": {
                        "title": "Maximum permits",
                        "minimum": 1,
                        "maximum": 50000,
                        "type": "integer",
                        "description": "Stop after saving this many permits. Keep the first run small.",
                        "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
