# Virginia DPOR Contractor License Leads Scraper (`automation-lab/virginia-dpor-contractor-license-leads-scraper`) Actor

🏗️ Export official Virginia DPOR Class A, B, and C contractor licenses with lead-ready specialties, expiration dates, addresses, and public emails.

- **URL**: https://apify.com/automation-lab/virginia-dpor-contractor-license-leads-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

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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 web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

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

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

## Virginia DPOR Contractor License Leads Scraper

Export official Virginia contractor license records from the Department of Professional and Occupational Regulation (DPOR).

Turn Class A, B, and C regulant lists into structured, filterable contractor leads with certificate numbers, business names, addresses, specialties, expiration dates, and public emails.

The Actor reads DPOR's official bulk files directly.
No browser, login, or user-supplied URL is required.
The files are advertised as refreshed every five business days, making the Actor useful for scheduled prospecting and compliance checks.

### What does this Virginia contractor license scraper do?

The Actor downloads the official DPOR contractor lists for the classes you select.
It validates every source header, parses tab-delimited rows, normalizes dates and whitespace, applies your filters, removes duplicates, and saves matching records.

Use it to:

- 🏗️ build Virginia contractor lead lists;
- ✉️ find records containing public business emails;
- 🧰 target DPOR specialty codes such as `HIC`, `ELE`, or `PLB`;
- 📍 segment businesses by city, state, or ZIP code;
- 📅 monitor certification and expiration dates;
- ✅ retain official source URLs and source values for auditing.

The Actor does not invent an active/inactive status.
DPOR's bulk contractor files do not publish that field, so the output preserves dates without making unsupported status claims.

### Who is it for?

#### Construction suppliers

Find contractors by territory and specialty for material, equipment, and service outreach.
Filter to records with email addresses before importing the dataset into a CRM.

#### Insurance and compliance teams

Schedule exports and monitor licenses approaching an expiration window.
Keep source URLs and fetched timestamps with every record.

#### Contractor marketplaces

Populate or refresh Virginia provider profiles with official certificate numbers, classes, specialties, and business locations.

#### Local B2B sales teams

Create city- or ZIP-specific lists for Richmond, Norfolk, Virginia Beach, Roanoke, or any other territory represented in DPOR data.

#### Data engineers

Use the Apify API, webhooks, schedules, dataset exports, and integrations to feed a warehouse or enrichment pipeline.

### Why use official Virginia DPOR bulk data?

- **Authoritative source:** records come from Virginia DPOR.
- **Bulk coverage:** one run can process Class A, B, and C files.
- **Lead-ready fields:** many source records include a public email.
- **Transparent provenance:** every item includes its exact source file URL.
- **Repeatable refreshes:** schedule the Actor around DPOR's five-business-day update cadence.
- **Fail-safe parsing:** unexpected header changes stop the run instead of silently shifting columns.

### What contractor license data can I extract?

| Field | Description |
|---|---|
| `certificateNumber` | DPOR certificate number preserved as text |
| `individualName` | Individual name when supplied |
| `businessName` | Licensed business name |
| `licenseClass` | Class A, B, or C |
| `specialties` | Normalized DPOR specialty code array |
| `specialtiesSource` | Specialty text exactly as published after whitespace cleanup |
| `email` | Public email from the source file |
| `fullAddress` | Combined mailing/business address |
| `city`, `state`, `zipCode` | Location components |
| `expirationDate` | ISO `YYYY-MM-DD` expiration date |
| `certificationDate` | ISO `YYYY-MM-DD` certification date |
| `expirationDateSource` | Original DPOR date value |
| `board`, `occupation` | DPOR board and occupation codes |
| `sourceUrl` | Official Class A, B, or C text file |
| `fetchedAt` | UTC fetch timestamp |

Separate address lines, PO box, ZIP extension, province, country, and international postal code are also retained.

### How to run the scraper

1. Open the Actor input page.
2. Select one or more license classes.
3. Optionally enter specialty, business-name, or location filters.
4. Optionally choose an expiration-date window.
5. Choose whether records must contain an email.
6. Set a maximum result count.
7. Click **Start**.
8. Open the dataset to preview or export JSON, CSV, Excel, XML, RSS, or HTML.

For a quick first run, keep Class A selected, require an email, and request 25 results.

### Input parameters

| Input | Type | Default | Purpose |
|---|---|---:|---|
| `licenseClasses` | string array | `['A']` | Official contractor lists to process |
| `specialties` | string array | empty | Exact DPOR specialty codes; any match qualifies |
| `businessNames` | string array | empty | Case-insensitive business-name substrings |
| `cities` | string array | empty | Exact city matches |
| `states` | string array | empty | Exact state abbreviations |
| `zipCodes` | string array | empty | Exact five-digit ZIP codes |
| `expiresAfter` | date | empty | Inclusive lower expiration bound |
| `expiresBefore` | date | empty | Inclusive upper expiration bound |
| `emailRequirement` | enum | `any` | Any, with email, or without email |
| `maxResults` | integer | `100` | Maximum matching records, up to 50,000 |

Empty filter arrays mean “do not filter by this field.”
Date filtering excludes source values that cannot be safely normalized.

### Input examples

#### Public-email leads across all classes

```json
{
  "licenseClasses": ["A", "B", "C"],
  "emailRequirement": "withEmail",
  "maxResults": 500
}
````

#### Richmond home-improvement contractors

```json
{
  "licenseClasses": ["A"],
  "specialties": ["HIC"],
  "cities": ["RICHMOND"],
  "maxResults": 250
}
```

#### Virginia-address businesses expiring in a window

```json
{
  "licenseClasses": ["A", "B", "C"],
  "states": ["VA"],
  "expiresAfter": "2026-08-01",
  "expiresBefore": "2026-08-31",
  "maxResults": 1000
}
```

### Output example

```json
{
  "board": "27",
  "occupation": "05",
  "certificateNumber": "082040",
  "individualName": "",
  "businessName": "CORNERSTONE ENGINEERING AND CONSULTING SERVICES PLLC",
  "addressLine1": "1272 NELLIE JONES RD",
  "addressLine2": "",
  "poBox": "",
  "fullAddress": "1272 NELLIE JONES RD, LA CROSSE, VA, 23950",
  "city": "LA CROSSE",
  "state": "VA",
  "zipCode": "23950",
  "zipCodeExtension": "0000",
  "province": "",
  "country": "",
  "postalCode": "",
  "expirationDate": "2028-02-29",
  "expirationDateSource": "02/29/2028",
  "certificationDate": "2004-02-03",
  "certificationDateSource": "02/03/2004",
  "licenseClass": "A",
  "specialties": ["EMW", "ENV"],
  "specialtiesSource": "EMW ENV",
  "email": "bdougherty@cornerstoneusa.net",
  "sourceUrl": "https://www.dpor.virginia.gov/sites/default/files/Records%20and%20Documents/Regulant%20List/2705a__crnt.txt",
  "fetchedAt": "2026-07-22T00:00:00.000Z"
}
```

Empty source fields are exported as empty strings so CSV columns stay predictable.

### How much does it cost to scrape Virginia contractor licenses?

This Actor uses pay-per-event pricing:

- a **$0.005 start charge** covers source download and validation;
- an item charge applies to each contractor record saved;
- subscription tiers receive automatic per-record discounts.

| Apify plan tier | Price per contractor record | 1,000 records plus start |
|---|---:|---:|
| Free | $0.000026894 | $0.031894 |
| Bronze | $0.000023386 | $0.028386 |
| Silver | $0.000018241 | $0.023241 |
| Gold | $0.000014032 | $0.019032 |
| Platinum | $0.000010000 | $0.015000 |
| Diamond | $0.000010000 | $0.015000 |

The Console shows the exact estimated price before you start a run.
Filters can reduce output charges because only matching records are saved.
A 20-record prefilled run costs about $0.0055 before Apify credits.

Apify's Free plan includes monthly platform credits, which may cover small test exports depending on current plan terms.

### Specialty filtering tips

DPOR specialty values are compact codes, not descriptive labels.
Enter exact tokens such as `HIC` rather than a phrase such as “home improvement.”

- Use one code to target a narrow trade.
- Add several codes to accept records matching any one of them.
- Run a small unfiltered export first to inspect current codes.
- Preserve `specialtiesSource` when downstream systems need the source representation.

The Actor does not guess or enrich specialty labels, avoiding incorrect classifications when DPOR revises its code list.

### Lead-generation workflow

1. Select all relevant contractor classes.
2. Limit the dataset to your sales territory.
3. Set `emailRequirement` to `withEmail`.
4. Add specialty codes aligned with your offer.
5. Export the result to CSV or connect a webhook.
6. Deduplicate against your CRM using `certificateNumber` plus `licenseClass`.
7. Re-run after DPOR refreshes its lists.

Always apply appropriate outreach laws, consent rules, and suppression lists.
A published business email is data availability, not automatic marketing consent.

### Compliance and renewal monitoring workflow

Create an Apify schedule with an expiration window relevant to your review cycle.
Send the dataset to Slack, email, a webhook, or a database.
Compare certificate numbers with the previous snapshot.

Useful checks include:

- contractors newly entering an expiration window;
- changes in business location or public email;
- newly listed certification dates;
- specialty-code changes between snapshots;
- missing records requiring manual source verification.

Keep `fetchedAt`, raw dates, and `sourceUrl` for traceability.

### Integrations

#### Google Sheets

Use the Google Sheets integration to create a territory list for sales operations.
Map `certificateNumber` as a text column to preserve leading zeros.

#### Webhooks and CRMs

Trigger a webhook when the Actor finishes, then upsert records into HubSpot, Salesforce, Pipedrive, or your internal CRM.
Use certificate number, class, and specialties as the stable composite key.

#### Make and Zapier

Create no-code flows that notify account owners when matching contractor records appear or enter an expiration window.

#### Data warehouses

Pull dataset items through the API into BigQuery, Snowflake, PostgreSQL, or object storage.
Retain raw date and specialty fields for auditing.

### Run with the Apify API

Replace `APIFY_TOKEN` with your token.
The Actor ID is `automation-lab/virginia-dpor-contractor-license-leads-scraper`.

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/virginia-dpor-contractor-license-leads-scraper').call({
  licenseClasses: ['A', 'B', 'C'],
  emailRequirement: 'withEmail',
  maxResults: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/virginia-dpor-contractor-license-leads-scraper').call(run_input={
    'licenseClasses': ['A'],
    'specialties': ['HIC'],
    'maxResults': 100,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

#### cURL

```bash
curl -X POST \
  'https://api.apify.com/v2/acts/automation-lab~virginia-dpor-contractor-license-leads-scraper/runs?token=APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"licenseClasses":["A"],"emailRequirement":"withEmail","maxResults":25}'
```

### Use with MCP and AI assistants

Connect the Actor through Apify's MCP server and ask an assistant to run Virginia contractor research.

#### Claude Code

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/virginia-dpor-contractor-license-leads-scraper"
```

#### Claude Desktop, Cursor, or VS Code

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/virginia-dpor-contractor-license-leads-scraper"
    }
  }
}
```

Example prompts:

- “Find 100 Class A Virginia contractor records with public emails.”
- “Export Richmond HIC contractors and summarize counts by ZIP code.”
- “Find contractor licenses expiring next month and group them by class.”

### Data quality and reliability

The Actor verifies all 20 expected DPOR columns before parsing rows.
If DPOR adds, removes, or renames a column, the run fails with the affected class and schema difference.
This is safer than shifting values into the wrong fields.

It also:

- checks that source rank matches the selected file;
- rejects malformed user dates;
- fails closed for unparseable dates when date filters are active;
- retries bounded transient HTTP failures;
- deduplicates records before output;
- preserves source values next to normalized values.

### Responsible use and legality

The Actor accesses public government bulk files without bypassing authentication or technical controls.
Public availability does not remove your responsibility to use data lawfully.

Before using output:

- review Virginia DPOR's current terms and notices;
- comply with privacy, marketing, and consumer-protection rules;
- honor opt-outs and suppression lists;
- avoid harassment or discriminatory profiling;
- verify critical decisions against the official source;
- secure exported contact data appropriately.

This tool is not legal advice and does not certify that a contractor is active, insured, bonded, or suitable for work.

### Troubleshooting

#### Why did my specialty filter return no records?

DPOR uses exact specialty codes.
Run a small export without the specialty filter, inspect `specialties`, and retry with an observed code.
Do not enter a descriptive trade name unless it is itself a published token.

#### Why is an ISO date empty?

The original value remains in `expirationDateSource` or `certificationDateSource`.
An empty normalized date means the source value was blank or could not be safely parsed as `MM/DD/YYYY`.
When a date filter is active, such records are excluded.

#### Why are some business addresses outside Virginia?

Virginia contractor licenses may belong to businesses with out-of-state addresses.
Set `states` to `["VA"]` if you only want Virginia-address records.

#### Why did the run stop with a schema-change error?

DPOR changed a source header or row shape.
The Actor intentionally stops rather than returning misaligned data.
Open an Actor issue and include the run ID so the parser can be reviewed.

### FAQ

#### How often is the source updated?

Virginia DPOR states that regulant lists are updated every five business days.
The `fetchedAt` field tells you when this Actor downloaded a record.

#### Does this scrape every Virginia profession?

No.
This Actor focuses on contractor occupation code 05 and the official Class A, B, and C contractor files.

#### Does the output include phone numbers?

No.
The current official bulk files do not expose a phone column.
The Actor does not fabricate or enrich missing phone data.

#### Does it tell me whether a license is active?

No unsupported status is inferred.
Use the published expiration and certification dates, and verify important cases directly with DPOR.

#### Can I export all records?

Yes, select A, B, and C and raise `maxResults` up to 50,000.
For first runs, use a smaller limit to validate your workflow and expected cost.

#### Can I schedule recurring exports?

Yes.
Use Apify Schedules and connect the resulting dataset to your preferred integration or webhook.

### Related scrapers

Explore complementary actors from Automation Lab:

- [Arizona ROC Contractor License Scraper](https://apify.com/automation-lab/az-roc-contractor-license-scraper)
- [Washington Contractor License Scraper](https://apify.com/automation-lab/washington-contractor-license-scraper)
- [Oregon Contractor License Scraper](https://apify.com/automation-lab/oregon-contractor-license-scraper)
- [Professional License Verifier](https://apify.com/automation-lab/professional-license-verifier)

Choose this Actor when you need Virginia DPOR bulk contractor files, public emails, and specialty-level filtering.
Use a state-specific related Actor for another licensing authority or a verifier for single-record checks.

### Support

If a run fails or a DPOR file changes, open an issue from the Actor page.
Include:

- the run ID;
- the input used;
- the selected license classes;
- the expected filter result;
- whether the problem is reproducible.

Do not include private credentials or unrelated personal data.
The source URL in each item helps reproduce data-quality questions quickly.

# Actor input Schema

## `licenseClasses` (type: `array`):

Choose one or more Virginia contractor license ranks to download from DPOR.

## `specialties` (type: `array`):

Return records containing any exact DPOR specialty code, for example HIC, ELE, PLB, or HVAC.

## `businessNames` (type: `array`):

Return businesses containing any supplied text, case-insensitively.

## `cities` (type: `array`):

Return exact city matches, case-insensitively, such as Richmond or Norfolk.

## `states` (type: `array`):

Return exact state abbreviations. Use VA to keep only Virginia addresses.

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

Return exact five-digit ZIP code matches.

## `expiresAfter` (type: `string`):

Keep licenses expiring on or after this date. Unparseable source dates fail closed.

## `expiresBefore` (type: `string`):

Keep licenses expiring on or before this date. Unparseable source dates fail closed.

## `emailRequirement` (type: `string`):

Include all records, only records with a public email, or only records without one.

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

Stop after this many matching contractor license records.

## Actor input object example

```json
{
  "licenseClasses": [
    "A"
  ],
  "specialties": [],
  "businessNames": [],
  "cities": [],
  "states": [],
  "zipCodes": [],
  "emailRequirement": "withEmail",
  "maxResults": 20
}
```

# Actor output Schema

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

Open the default dataset table containing normalized contractor licenses, specialties, addresses, expiration dates, public emails, and source provenance.

# 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 = {
    "licenseClasses": [
        "A"
    ],
    "specialties": [],
    "businessNames": [],
    "cities": [],
    "states": [],
    "zipCodes": [],
    "emailRequirement": "withEmail",
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/virginia-dpor-contractor-license-leads-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 = {
    "licenseClasses": ["A"],
    "specialties": [],
    "businessNames": [],
    "cities": [],
    "states": [],
    "zipCodes": [],
    "emailRequirement": "withEmail",
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/virginia-dpor-contractor-license-leads-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 '{
  "licenseClasses": [
    "A"
  ],
  "specialties": [],
  "businessNames": [],
  "cities": [],
  "states": [],
  "zipCodes": [],
  "emailRequirement": "withEmail",
  "maxResults": 20
}' |
apify call automation-lab/virginia-dpor-contractor-license-leads-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/virginia-dpor-contractor-license-leads-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Virginia DPOR Contractor License Leads Scraper",
        "description": "🏗️ Export official Virginia DPOR Class A, B, and C contractor licenses with lead-ready specialties, expiration dates, addresses, and public emails.",
        "version": "0.1",
        "x-build-id": "AhfORqnjbhv1m8sA4"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/automation-lab~virginia-dpor-contractor-license-leads-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-automation-lab-virginia-dpor-contractor-license-leads-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~virginia-dpor-contractor-license-leads-scraper/runs": {
            "post": {
                "operationId": "runs-sync-automation-lab-virginia-dpor-contractor-license-leads-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~virginia-dpor-contractor-license-leads-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-automation-lab-virginia-dpor-contractor-license-leads-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": {
                    "licenseClasses": {
                        "title": "🏗️ License classes",
                        "type": "array",
                        "description": "Choose one or more Virginia contractor license ranks to download from DPOR.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "A",
                                "B",
                                "C"
                            ],
                            "enumTitles": [
                                "Class A",
                                "Class B",
                                "Class C"
                            ]
                        },
                        "default": [
                            "A"
                        ]
                    },
                    "specialties": {
                        "title": "Specialty codes",
                        "type": "array",
                        "description": "Return records containing any exact DPOR specialty code, for example HIC, ELE, PLB, or HVAC.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "businessNames": {
                        "title": "Business name contains",
                        "type": "array",
                        "description": "Return businesses containing any supplied text, case-insensitively.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "cities": {
                        "title": "Cities",
                        "type": "array",
                        "description": "Return exact city matches, case-insensitively, such as Richmond or Norfolk.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "states": {
                        "title": "Business states",
                        "type": "array",
                        "description": "Return exact state abbreviations. Use VA to keep only Virginia addresses.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "zipCodes": {
                        "title": "ZIP codes",
                        "type": "array",
                        "description": "Return exact five-digit ZIP code matches.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "expiresAfter": {
                        "title": "Expires on or after",
                        "type": "string",
                        "description": "Keep licenses expiring on or after this date. Unparseable source dates fail closed."
                    },
                    "expiresBefore": {
                        "title": "Expires on or before",
                        "type": "string",
                        "description": "Keep licenses expiring on or before this date. Unparseable source dates fail closed."
                    },
                    "emailRequirement": {
                        "title": "Email availability",
                        "enum": [
                            "any",
                            "withEmail",
                            "withoutEmail"
                        ],
                        "type": "string",
                        "description": "Include all records, only records with a public email, or only records without one.",
                        "default": "any"
                    },
                    "maxResults": {
                        "title": "Maximum contractor records",
                        "minimum": 1,
                        "maximum": 50000,
                        "type": "integer",
                        "description": "Stop after this many matching contractor license records.",
                        "default": 100
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
