# Delaware Contractor License Lookup & Export (DOR + DPR) (`scrapebench/delaware-contractor-license-lookup`) Actor

Export every current Delaware contractor business licence (13,215 on 2026-10-07) with street address, plus active DPR electrical, plumbing and HVACR licences. Filter by trade, residency, city, ZIP or name.

- **URL**: https://apify.com/scrapebench/delaware-contractor-license-lookup.md
- **Developed by:** [ScrapeBench](https://apify.com/scrapebench) (community)
- **Categories:** Lead generation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.004 / license record

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

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Delaware Contractor License Lookup & Export (DOR + DPR)

### Pain points

- Delaware splits contractor licensing between two agencies: the Division of Revenue licenses contractor businesses and the Division of Professional Regulation licenses electricians, plumbers and HVACR technicians, in two separate open-data sets with different columns.
- The business-licence set holds every kind of Delaware business; contractors are four of its categories, and a firm is listed once per trade name, so 13,215 contractor licences arrive as 13,417 rows (2026-10-07).
- The professional-licence set covers 38 professions and every status ever recorded: 31,184 electrical and plumbing/HVACR rows, of which 7,205 are active trade licences once homeowner permits are set aside (2026-10-07).

### What we solve

- One run reads both rosters and returns them in one table, each row tagged with the roster it came from.
- One row per licence number: a firm's trade names (DBAs) are folded into a list instead of repeating the firm, and an old licence term never shadows the current one.
- Filters are sent to the state's own query API, so a city, ZIP, name or trade run reads only the matching licences; a value the actor does not recognise is dropped and logged, never widened to the whole state.

### Summary

Get Delaware's contractor licences as clean data from the state's two official public-domain rosters on data.delaware.gov. The Division of Revenue roster gives every current contractor business licence (13,215 on 2026-10-07: 8,588 resident and 4,627 non-resident) with legal name, trade names, category, licence term and street address. The Division of Professional Regulation roster adds 7,205 active electrical, plumbing and HVACR licences held by individuals, with licence type, status, issue and expiry dates, city and ZIP. Leave the input empty for both rosters statewide, or narrow by trade, residency, status, city, ZIP or name. Neither roster publishes a phone number or email address, and the actor does not add any. Pay only per licence returned.

### Who it's for

- Suppliers, distributors and software vendors selling to Delaware contractors and out-of-state contractors licensed to work there
- General contractors and property managers checking that a Delaware subcontractor holds a current business licence or trade licence
- Insurers, sureties and lenders verifying licence category, status and expiry
- Data teams loading a statewide Delaware contractor table into a CRM or warehouse

### How to use

Set the input, run the actor, and collect results from the run's dataset (export to JSON/CSV/Excel, or pull via the Apify API). Example input:

```json
{
  "city": "Dover",
  "maxResults": 1000
}
```

See **Inputs** below for every available field.

### What you get

One row per record:

| Field | Description |
|---|---|
| `license_number` | State licence number, one row per licence within each roster |
| `dataset` | business_license (Division of Revenue) or trade_license (DPR) |
| `license_category` | Business category (e.g. RESIDENT CONTRACTOR) or DPR licence type (e.g. Master Electrician) |
| `board` | Electrical Examiners or Plumbing/HVACR (trade licences) |
| `residency` | resident or non_resident (business licences) |
| `status` | DPR status, e.g. Active or Expired (trade licences) |
| `business_name` | Legal business name |
| `trade_names` | Other 'doing business as' names on the same licence |
| `person_name` | Licensee's name (trade licences held by individuals) |
| `issue_date` | Trade-licence issue date |
| `valid_from` | Start of the current business-licence term |
| `expiration_date` | End of the current licence term |
| `address` | Street address (business licences only) |
| `city` | City |
| `address_state` | State of the address (out-of-state holders included) |
| `zip_code` | ZIP or ZIP+4 |
| `source_url` | data.delaware.gov API query returning this licence's source rows |

Sample:

```json
{
  "license_number": "1989001012",
  "dataset": "business_license",
  "license_category": "RESIDENT CONTRACTOR",
  "board": null,
  "residency": "resident",
  "status": null,
  "business_name": "HATZEL & BUEHLER INC",
  "trade_names": [],
  "person_name": null,
  "issue_date": null,
  "valid_from": "2025-01-01",
  "expiration_date": "2027-12-31",
  "address": "1 RIGHTER PARKWAY, SUITE 300",
  "city": "WILMINGTON",
  "address_state": "DE",
  "zip_code": "19803",
  "state": "DE",
  "source_url": "https://data.delaware.gov/resource/5zy2-grhr.json?license_number=1989001012"
}
```

### Inputs

| Field | Required | Type | Default | Description |
|---|---|---|---|---|
| `source` | no | string | `"both"` | Which Delaware roster to read. 'business' = contractor business licences from the Division of Revenue (firms, with street address). 'trade' = electrical, plumbing and HVACR licences from the Division of Professional Regulation (individuals, city and ZIP only). 'both' returns business licences first, then trade licences, up to Maximum results. A filter one roster cannot apply (trade or a non-active status on business licences, residency on trade licences) leaves that roster out rather than being ignored. |
| `residency` | no | string | `"all"` | Resident or non-resident contractor business licence category. Applies to business licences only; setting it leaves trade licences out. |
| `trade` | no | string | — | A DPR trade: 'electrical', 'plumbing', 'hvacr', 'homeowner' (homeowner electrical permits, left out unless asked for), or an exact licence type such as 'Master Electrician', 'Journeyperson Electrician' or 'Master HVACR Restricted'. Applies to trade licences only; setting it leaves business licences out. An unrecognised value is ignored with a log line; if nothing you gave is recognised, the run returns a free row saying so instead of the whole state. |
| `trades` | no | array | `[]` | Several trades in ONE run, e.g. plumbing and hvacr. Combined with 'Trade' if you fill both. |
| `status` | no | string | `"active"` | Trade-licence status. 'active' (default) keeps current licences; 'all' includes expired, closed and revoked ones. The business roster lists only current licences, so 'active' and 'all' both return all of it and any other status leaves it out. |
| `city` | no | string | — | City on the licence, exact match ignoring case, e.g. 'Dover' or 'Wilmington'. Partial city names do not match. |
| `cities` | no | array | `[]` | Several cities in ONE run. Combined with 'City' if you fill both. |
| `zip` | no | string | — | ZIP on the licence, 5 digits (a ZIP+4 is accepted and matched on its first 5). |
| `zips` | no | array | `[]` | Several ZIPs in ONE run. Combined with 'ZIP code' if you fill both. |
| `name` | no | string | — | Text the name contains (case-insensitive): the legal business name or any trade name (DBA) on business licences, or 'LAST,FIRST' on trade licences, e.g. 'ELECTRIC' or 'SMITH'. |
| `names` | no | array | `[]` | Several name fragments in ONE run; a licence matching any of them is returned once. The run log says how many returned licences each one matched. |
| `maxResults` | no | integer | `500` | Cap on licences returned for the whole run (a spend control). Both rosters together are about 20,400 current licences, so 100000 returns everything that matches. The run log states how many matched when the cap cuts it short. |
| `proxyConfiguration` | no | object | `{"useApifyProxy": false}` | Optional. data.delaware.gov answers direct requests; enable a proxy only if runs come back with a 'blocked' notice. |

### Pricing (Pay Per Event)

You pay per result (`dataset-item`) — **no charge for empty runs**. Example: **881 Dover contractor and trade licences** at *$0.004/result* ≈ **$3.52**.

The full statewide export (13,215 business + 7,205 trade licences = 20,420 rows on 2026-10-07) is about $82. The default run (500 rows) costs $2.00. Apify platform usage is billed separately.

### Use cases

- Statewide export: pull all 20,420 current contractor and trade licences in one run and load them into your CRM.
- Territory list: every contractor business licence and active trade licence in Dover (881 on 2026-10-07), with street address for the firms.
- Trade list: every active Master HVACR and HVACR Restricted licence in the state (1,238 on 2026-10-07) with city and ZIP.
- Out-of-state firms: filter residency to non_resident for the 4,627 contractors based elsewhere who are licensed to work in Delaware.

### Why this actor

- Both Delaware contractor rosters in one table: 13,215 current business licences and 7,205 active trade licences (5,027 electrical, 940 plumbing, 1,238 HVACR), counted 2026-10-07.
- Street address on every business licence (13,215 of 13,215), and trade names folded into a list on the 4,070 licences that file one or more.
- One row per licence number in each roster (13,215 distinct of 13,215 business rows, 7,205 of 7,205 trade rows).
- Read live from the state's own public-domain open data on every run; a statewide run takes about 5 seconds.
- Pay per licence returned; outage, bad-filter and no-match rows are free.

### Limitations & updates

Covers Delaware contractor business licences (current only) and DPR electrical, plumbing and HVACR licences. No phone numbers or emails: neither roster publishes them. Trade licences have no street address, only city, state and ZIP. The rosters are not joined to each other. Homeowner electrical permits are left out unless asked for with trade 'homeowner'. 'valid_from' is the start of the current business-licence term, not the date the firm was first licensed. DPR files a 1900 placeholder as the issue date on some old licences; those are returned as null. The state refreshes the datasets on its own schedule (last update 2026-09-29 when counted). Data: State of Delaware via data.delaware.gov, public domain. If the state's site does not answer, the run returns a free row saying so instead of an empty dataset.

### FAQ

**Where does the data come from?**

From two public-domain datasets on data.delaware.gov: 'Delaware Business Licenses' (Department of Finance, Division of Revenue; the four contractor categories) and 'Professional and Occupational Licensing' (Department of State, Division of Professional Regulation; the Electrical Examiners and Plumbing/HVACR boards). Both were last updated 2026-09-29 when counted. The actor queries them on every run.

**Does it include phone numbers or emails?**

No. Neither roster publishes a phone number or email address, and the actor does not add any. Business licences carry a street address; trade licences carry only city, state and ZIP.

**What is the difference between the two rosters?**

A business licence is the Division of Revenue licence a contracting firm needs to work in Delaware, filed as RESIDENT CONTRACTOR or NON-RESIDENT CONTRACTOR (plus 68 construction transportation contractors). A trade licence is held by an individual electrician, plumber or HVACR technician, from master down to apprentice. Every row says which roster it came from in 'dataset'. The two are not joined: the rosters share no common key, and matching firm names to people's names would be guesswork.

**Are expired licences included?**

The business roster lists only current licences (every term runs to December 2026 or later). Trade licences default to Active; set status to 'all' for every status DPR records (18,591 trade licences on 2026-10-07) or pick one such as expired or revoked.

**What happens if I type a trade or ZIP the actor does not know?**

That value is ignored and the run log says so. If none of the values you gave for a filter is recognised, the run returns one free row explaining it instead of the whole state. A filter only one roster can apply leaves the other roster out: a trade filter returns trade licences only, a residency filter business licences only.

**How am I charged?**

$0.004 per licence returned. The default input returns the first 500 licences ($2.00); the full statewide export of 20,420 licences is about $82. Rows explaining an outage, an unrecognised filter or an empty result are free.

### Which actor to choose

Part of the contractor-data suite — pick the one that fits your goal:

- **Virginia Contractor License Lookup (DPOR Bulk)** — You need the same kind of statewide licence export for Virginia, with email.
- **Arkansas Contractor License Lookup & Verify (ACLB)** — You need Arkansas contractor licences, in bulk or one at a time.
- **Multi-State Contractor & Trade License Lookup** — You want the same contractor checked across several states in one run.
- **Iowa Contractor License Lookup & Export (DIAL)** — You need Iowa contractors — every active DIAL registration statewide, with phone and email, filtered by trade, county, city or ZIP.
- **Mississippi Contractor License Lookup & Export (MSBOC)** — You need Mississippi contractors — the active MSBOC roster with phone, street address and classifications, by county or class.
- **Ohio Contractor License Lookup & Export (OCILB)** — You need Ohio electrical, HVAC, plumbing, hydronics or refrigeration contractors — the full OCILB roster, by trade and county.
- **Nebraska Contractor Registration Lookup & Export (NDOL)** — You need Nebraska contractors — every current NDOL registration, by service and county, with phone on request.

### Guides & use cases

Written up on **[scrapebench.dev](https://scrapebench.dev)** — the bench that runs and verifies this actor against the live source every night:

- **How-to:** [How to run Delaware Contractor License Lookup & Export (DOR + DPR)](https://scrapebench.dev/guides/how-to-delaware-contractor-license-lookup/)
- **Use case:** [List Dover, Delaware Contractor and Trade Licences](https://scrapebench.dev/use-cases/dover-contractor-licences/)

More actors, coverage and nightly verification results: **[scrapebench.dev](https://scrapebench.dev)**

### Works with AI assistants (MCP)

Callable as an MCP tool, so Claude, Cursor, VS Code Copilot and other MCP clients can run it directly. Grab the config from the [MCP tab](https://apify.com/scrapebench/delaware-contractor-license-lookup/api/mcp) on this page — Apify hosts the server and keeps that snippet current, and OAuth signs you in on first connect, so no API token goes in your config file.

Then just ask:

> "List the current Delaware contractor business licences in Dover, with street addresses."

That input (source business, city Dover) returned 670 licences on 2026-10-07. With no filters it exports both rosters statewide (20,420 rows), so set a city, trade or ZIP before running it from an agent. Runs started this way bill exactly like any other run.

# Changelog

This Actor's version history is a separate document: https://apify.com/scrapebench/delaware-contractor-license-lookup/changelog.md

# Actor input Schema

## `source` (type: `string`):

Which Delaware roster to read. 'business' = contractor business licences from the Division of Revenue (firms, with street address). 'trade' = electrical, plumbing and HVACR licences from the Division of Professional Regulation (individuals, city and ZIP only). 'both' returns business licences first, then trade licences, up to Maximum results. A filter one roster cannot apply (trade or a non-active status on business licences, residency on trade licences) leaves that roster out rather than being ignored.

## `residency` (type: `string`):

Resident or non-resident contractor business licence category. Applies to business licences only; setting it leaves trade licences out.

## `trade` (type: `string`):

A DPR trade: 'electrical', 'plumbing', 'hvacr', 'homeowner' (homeowner electrical permits, left out unless asked for), or an exact licence type such as 'Master Electrician', 'Journeyperson Electrician' or 'Master HVACR Restricted'. Applies to trade licences only; setting it leaves business licences out. An unrecognised value is ignored with a log line; if nothing you gave is recognised, the run returns a free row saying so instead of the whole state.

## `trades` (type: `array`):

Several trades in ONE run, e.g. plumbing and hvacr. Combined with 'Trade' if you fill both.

## `status` (type: `string`):

Trade-licence status. 'active' (default) keeps current licences; 'all' includes expired, closed and revoked ones. The business roster lists only current licences, so 'active' and 'all' both return all of it and any other status leaves it out.

## `city` (type: `string`):

City on the licence, exact match ignoring case, e.g. 'Dover' or 'Wilmington'. Partial city names do not match.

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

Several cities in ONE run. Combined with 'City' if you fill both.

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

ZIP on the licence, 5 digits (a ZIP+4 is accepted and matched on its first 5).

## `zips` (type: `array`):

Several ZIPs in ONE run. Combined with 'ZIP code' if you fill both.

## `name` (type: `string`):

Text the name contains (case-insensitive): the legal business name or any trade name (DBA) on business licences, or 'LAST,FIRST' on trade licences, e.g. 'ELECTRIC' or 'SMITH'.

## `names` (type: `array`):

Several name fragments in ONE run; a licence matching any of them is returned once. The run log says how many returned licences each one matched.

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

Cap on licences returned for the whole run (a spend control). Both rosters together are about 20,400 current licences, so 100000 returns everything that matches. The run log states how many matched when the cap cuts it short.

## `proxyConfiguration` (type: `object`):

Optional. data.delaware.gov answers direct requests; enable a proxy only if runs come back with a 'blocked' notice.

## Actor input object example

```json
{
  "source": "both",
  "residency": "all",
  "trade": "hvacr",
  "trades": [],
  "status": "active",
  "cities": [],
  "zips": [],
  "names": [],
  "maxResults": 500,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Each row is one licence: number, roster, category, status, dates, business or licensee name, and address.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapebench/delaware-contractor-license-lookup").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("scrapebench/delaware-contractor-license-lookup").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{}' |
apify call scrapebench/delaware-contractor-license-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapebench/delaware-contractor-license-lookup"
        }
    }
}
```

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

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/gHdrkW3ff7DyQnUlT/builds/xv8wjPfzBcrUYX4oz/openapi.json
