# Wisconsin Contractor License Lookup & Leads Scraper (`scrapebench/wisconsin-contractor-license-lookup`) Actor

Licensed contractors in Wisconsin from three public rosters: Milwaukee home improvement contractors, Madison City Engineering contractors and DNR well drillers and pump installers. Phone, address or email, licence number, expiry.

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

## Pricing

$0.002 / contractor 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

## Wisconsin Contractor License Lookup & Leads Scraper

### Pain points

- Wisconsin's state licence lookup (DSPS LicensE) shows a name and a credential, no phone or address, one search at a time.
- Milwaukee publishes its licensed home improvement contractors as a 34-page PDF (checked 2026-11-06), not a spreadsheet.
- Madison's licensed and prequalified contractors sit in a report viewer, split into three categories and some 90 work tasks.

### What we solve

- Three rosters in one dataset: 1,205 Milwaukee home improvement licences, 363 Madison City Engineering firms and 1,604 DNR well and pump licences (November 6, 2026).
- One clean table: business, licence number where the source has one, trade(s), expiry, phone, street address (Milwaukee, DNR) and email (Madison, DNR).
- Filter by locality (Milwaukee, Madison, Statewide) and by trade, and by expiry date; look up a name or licence number across all three.

### Summary

Wisconsin contractor licences with contact details, from the three public rosters that publish them. Milwaukee: every home improvement contractor the City licenses (1,205 licences on November 6, 2026), with licence number, expiry, business, licensed agent, street address and phone (phone on 1,203). Madison: every firm City Engineering licenses for right-of-way work or prequalifies for public works and utility work (363 firms), with the work tasks it is approved for, phone and email (352 each) and expiry; Madison publishes no address or licence number. Statewide: the Department of Natural Resources' well drillers, pump installers, heat-exchange drillers, well filling and sealing and property-transfer well inspectors (1,604 licences; one row per licence carrying every DNR directory it is in), with licence number, phone, mailing address and email (1,549). The state's own DSPS lookup publishes no contact, so it is not used; this actor adds other Wisconsin cities as they are read. Exports read a stored copy; lookups read the rosters live. Pay only per row returned.

### Who it's for

- Building-material suppliers, lenders and insurers selling to licensed home improvement contractors in the Milwaukee area
- Utilities, engineering firms and general contractors finding Madison-approved subcontractors by work task
- Pump, well-equipment and water-treatment suppliers reaching Wisconsin's licensed well drillers and pump installers
- Homeowners and property managers checking a contractor's Milwaukee licence and expiry

### How to use

This actor does two jobs. Run it, then collect results from the run's dataset (export to JSON/CSV/Excel, or pull via the Apify API).

**Get a list (export):** no names, just filters; returns the whole matching list.

```json
{
  "categories": [
    "Home Improvement Contractor"
  ],
  "maxResults": 2000
}
```

**Check specific firms (lookup):** put company names or licence numbers in `mode`, `queries`; **Inputs** below says how each is matched.

```json
{
  "mode": "lookup",
  "queries": [
    "Concrete",
    "HICN 0205318"
  ],
  "maxResults": 20
}
```

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

### What you get

One row per record:

| Field | Description |
|---|---|
| `license_number` | The source's licence number: Milwaukee HICN …, DNR licence no.; Madison publishes none |
| `business_name` | Business as the source lists it; name holds the same |
| `classifications` | Trade(s): Home Improvement Contractor (Milwaukee), City Engineering work tasks (Madison), DNR licence types (Statewide) |
| `license_type` | The first trade |
| `expiration_date` | Licence or approval expiry (YYYY-MM-DD); DNR prints none |
| `status` | Active or Expired, derived from the expiry (the sources list current licences only); DNR rows are Active while listed |
| `phone` | Phone as printed; phone_e164 holds it as +1XXXXXXXXXX |
| `email` | Email (Madison, DNR) |
| `address` | Street address (Milwaukee: business address; DNR: mailing address); city and zip_code beside it |
| `person_name` | DNR: the licensed person where the licence is held by a person |
| `county` | DNR: the county the DNR directory lists the licensee under; extras.counties_listed when several (filling/sealing and inspectors list every county served) |
| `extras.locality` | Which roster the row comes from: Milwaukee, Madison or Statewide |
| `extras.contact_name` | Milwaukee: the licensed agent; extras.contact_role holds Agt or SP |
| `extras.approvals` | Madison: right-of-way licence, public works prequalification and/or utility approval |
| `extras.other_work` | Madison: the firm's own description of other work it is prequalified for |
| `source_url` | The roster the row was read from, tagged with the licence number or firm |

Sample:

```json
{
  "license_number": "HICN 0205308",
  "business_name": "2 Fast 2 Contractors",
  "classifications": [
    "Home Improvement Contractor"
  ],
  "license_type": "Home Improvement Contractor",
  "expiration_date": "2027-08-13",
  "status": "Active",
  "phone": "(414) 788-2252",
  "phone_e164": "+14147882252",
  "address": "4175 N 68th St",
  "city": "Milwaukee",
  "zip_code": "53216",
  "state": "WI",
  "source_url": "https://staticwebfiles.milwaukee.gov/main/citygov/council/licreports/ValidContractorLicenseReport.pdf#license-HICN0205308",
  "extras": {
    "locality": "Milwaukee",
    "contact_name": "Sheldon B Cruickshank",
    "contact_role": "Agt",
    "expires": "2027-08-13",
    "aldermanic_district": "2",
    "police_district": "7"
  }
}
```

### Inputs

| Field | Required | Type | Default | Description |
|---|---|---|---|---|
| `mode` | no | string | `"auto"` | export: no names, just filters; returns the whole matching list. lookup / verify: put company names (matched if contained in the company name) or licence numbers (exact) in 'queries'. auto picks the mode for you. |
| `query` | no | string | — | A business name (or listing number) to look up live. Kept alongside 'queries' for saved tasks. |
| `queries` | no | array | `[]` | A business name (or listing number) to look up live. Several values in one run; combined with 'query'. |
| `locality` | no | string | — | Only listings in this locality. Kept alongside 'localities' for saved tasks. |
| `localities` | no | array | `[]` | Only listings in this locality. Several values in one run; combined with 'locality'. |
| `status` | no | string | — | Only listings in this status. Kept alongside 'statuses' for saved tasks. |
| `statuses` | no | array | `[]` | Only listings in this status. Several values in one run; combined with 'status'. |
| `categories` | no | array | `[]` | Only rows from this trade (one or more). Available: Asbestos Removal, Asphalt Paver, Asphalt Paving, Blasting, Boring - Pipe Jacking, Bridge Construction and - or Repair, Building Automation Systems, Building Construction Other Tasks, Building Demolition, Concrete, Concrete Bases and Other Concrete Work, Concrete Layer, Concrete Paving, Concrete Removal, Concrete Sidewalk, Curb and Gutter, Misc. Flat Work, Doors and Windows, Dredging, Ecological Restoration, Electrical – Power, Lighting & Communications, Elevator – Lifts, Fencing, Fiber Optic Cable - Conduit Installation, Fire Suppression - Protection, Floor Covering (including carpet, ceramic tile installation, rubber, VCT, wood, etc.), Furnishings – Furniture and Window Treatments, … (94 in all; an unknown name returns the full list, free). |
| `licenseTypes` | no | array | `[]` | Same filter as 'Trade', under the name every state licence actor takes; the two lists are combined. |
| `expiresAfter` | no | string | — | Only licences expiring on or after this date (YYYY-MM-DD). Licences with no published expiry are left out when set. |
| `expiresBefore` | no | string | — | Only licences expiring on or before this date (YYYY-MM-DD): renewals coming due. |
| `maxResults` | no | integer | `500` | Per query in lookup mode; per run in export mode. |
| `proxyConfiguration` | no | object | `{"useApifyProxy": false}` | Used only for live lookups; exports read the stored snapshot. |

### Pricing (Pay Per Event)

You pay per result (`dataset-item`) — **no charge for empty runs**. Example: **1000 license matches** at *$0.004/result* ≈ **$4.00**.

Notices (unknown trade, no match, source unavailable) are free. Apify platform usage is billed separately per your plan.

### Use cases

- Sales lists: every Milwaukee-licensed home improvement contractor with street address and phone.
- Subcontractor sourcing: Madison firms approved for a task (concrete removal, sewer laterals, traffic control …) with phone and email.
- Supplier outreach: every DNR-licensed pump installer or well driller, with email and county.
- Licence checks: confirm a Milwaukee HICN number and its expiry before work starts.

### Why this actor

- Three Wisconsin rosters with contact details in one dataset; the state's own lookup has none.
- Milwaukee's PDF list as clean rows: licence, expiry, agent, street, phone.
- Madison's tasks across all three approval categories folded onto one row per firm.
- Pay per row; notices are free.

### Limitations & updates

Covers three rosters, not every Wisconsin contractor: Milwaukee home improvement licences (1,205), Madison City Engineering firms (363) and DNR well and pump licences (1,604), as read on 2026-11-06. State DSPS trades (dwelling contractor, electrical, plumbing, HVAC) are not included. Madison has no address or licence number; Milwaukee has no email; DNR has no expiry. Exports come from a stored copy (its date is in the run log).

### FAQ

**Where does the data come from?**

Milwaukee: the City Clerk's List of Valid City of Milwaukee Home Improvement Contractors (staticwebfiles.milwaukee.gov), regenerated daily. Madison: City Engineering's Prequalified Contractor List report (cityreports.cityofmadison.com), categories A, B and C. Statewide: the DNR's drilling and pump installing service directories (dnr.wisconsin.gov/topic/Wells/Contacts.html). Exports read a stored copy (the run log gives its date); lookups read the rosters live and fall back to the stored copy.

**Does it cover all of Wisconsin?**

Not for every trade. Wisconsin licenses dwelling contractors, electricians, plumbers and HVAC statewide through DSPS, whose public lookup shows no phone or address; those state licences are not included. This actor reads the rosters that publish contact: Milwaukee's home improvement licences, Madison's City Engineering approvals and the DNR's statewide well and pump licences. More Wisconsin cities are added as they are read.

**Which fields does each roster have?**

Milwaukee: licence number, expiry, business, licensed agent, street, city, ZIP, aldermanic and police district, phone; no email. Madison: firm, work tasks, approval category, phone, fax, email, expiry; no address and no licence number. DNR: licence number, name (person or business), phone, mobile, mailing address, email, county; no expiry.

**Are expired licences included?**

The sources list current licences only. Status is derived from the expiry date (Milwaukee, Madison); a DNR row is Active while the DNR lists it. Filter on Expires on or after / before to target renewals.

**How do I look up a firm or a licence number?**

Put names or licence numbers in queries and set mode to lookup. A name matches if it is contained in the business name; a number (HICN 0205318, a DNR licence no.) matches exactly. Lookups read all three rosters live.

**How am I charged?**

One event per row returned. Notices are free.

### 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 Wisconsin Contractor License Lookup & Leads Scraper](https://scrapebench.dev/guides/how-to-wisconsin-contractor-license-lookup/)
- **Use case:** [Milwaukee WI Licensed Home Improvement Contractors](https://scrapebench.dev/use-cases/milwaukee-wi-licensed-home-improvement-contractors/)

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/wisconsin-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 home improvement contractors licensed in Milwaukee, Wisconsin, with their street address, phone and licence expiry."

That is Trade Home Improvement Contractor (1,205 licences on 2026-11-06). Keep maxResults small on a first call. Runs started this way bill exactly like any other run.

### Data & lawful use

This actor collects publicly available information that the City of Milwaukee (City Clerk's License Division), the City of Madison (City Engineering) and the Wisconsin Department of Natural Resources (DNR) publishes for public
lookup — licence records, business listings and the contact details professionals list there.
Some of it identifies individuals (sole proprietors, licence holders, agents), so treat any
names, phone numbers and emails in your results as personal data.

When you run this actor, you decide what is collected and what it is used for, so you are the
controller of that data and we act only as your processor (Apify Standard Actor Contract).
You need a lawful basis for your use, must honour opt-out and deletion requests, and must
follow the marketing rules that apply to you (CAN-SPAM, TCPA, GDPR, CCPA and similar).
Don't use the output for unsolicited bulk messaging, for screening covered by the FCRA, or
for anything the source's own terms forbid.

Your results are stored in your own Apify account. We don't keep a copy of your results and
don't sell or share them.

### Disclaimer

This is an independent tool. It is not affiliated with, endorsed by or sponsored by
the City of Milwaukee (City Clerk's License Division), the City of Madison (City Engineering) and the Wisconsin Department of Natural Resources (DNR). Names and marks are used only to describe the data source. Records are
provided as published by the source and may be out of date or incomplete. For anything
consequential (hiring, a permit, a legal decision), confirm the record with the issuing
agency. You are responsible for making sure your use complies with applicable law and the
source's terms.

### Need help?

Open an issue on this actor's **Issues** tab and we'll respond there. Bug reports, missing
fields and feature requests are all welcome. Guides and examples: [scrapebench.dev](https://scrapebench.dev).

If you are a person named in this data and want your record removed from our copy, email
apify-help@scrapebench.dev; the source agency remains the official record.

Your run may be used to improve our services. If something looks off, or you want this actor to fit your use better, please share your run data with us: [Apify Console → Settings → Security → Share run data with developers](https://console.apify.com/settings/security). It lets us see exactly what went wrong and keep improving the actor.

If this actor saved you time, a short review on its Store page helps other buyers find it.

# Actor input Schema

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

export: no names, just filters; returns the whole matching list. lookup / verify: put company names (matched if contained in the company name) or licence numbers (exact) in 'queries'. auto picks the mode for you.

## `query` (type: `string`):

A business name (or listing number) to look up live. Kept alongside 'queries' for saved tasks.

## `queries` (type: `array`):

A business name (or listing number) to look up live. Several values in one run; combined with 'query'.

## `locality` (type: `string`):

Only listings in this locality. Kept alongside 'localities' for saved tasks.

## `localities` (type: `array`):

Only listings in this locality. Several values in one run; combined with 'locality'.

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

Only listings in this status. Kept alongside 'statuses' for saved tasks.

## `statuses` (type: `array`):

Only listings in this status. Several values in one run; combined with 'status'.

## `categories` (type: `array`):

Only rows from this trade (one or more). Available: Asbestos Removal, Asphalt Paver, Asphalt Paving, Blasting, Boring - Pipe Jacking, Bridge Construction and - or Repair, Building Automation Systems, Building Construction Other Tasks, Building Demolition, Concrete, Concrete Bases and Other Concrete Work, Concrete Layer, Concrete Paving, Concrete Removal, Concrete Sidewalk, Curb and Gutter, Misc. Flat Work, Doors and Windows, Dredging, Ecological Restoration, Electrical – Power, Lighting & Communications, Elevator – Lifts, Fencing, Fiber Optic Cable - Conduit Installation, Fire Suppression - Protection, Floor Covering (including carpet, ceramic tile installation, rubber, VCT, wood, etc.), Furnishings – Furniture and Window Treatments, … (94 in all; an unknown name returns the full list, free).

## `licenseTypes` (type: `array`):

Same filter as 'Trade', under the name every state licence actor takes; the two lists are combined.

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

Only licences expiring on or after this date (YYYY-MM-DD). Licences with no published expiry are left out when set.

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

Only licences expiring on or before this date (YYYY-MM-DD): renewals coming due.

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

Per query in lookup mode; per run in export mode.

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

Used only for live lookups; exports read the stored snapshot.

## Actor input object example

```json
{
  "mode": "auto",
  "queries": [],
  "localities": [],
  "statuses": [],
  "categories": [],
  "licenseTypes": [],
  "maxResults": 500,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One row per business listing; notices are free.

# 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/wisconsin-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/wisconsin-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/wisconsin-contractor-license-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapebench/wisconsin-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/8tbWXA6pWqTuzy9cS/builds/ZeCmhZNHGzAFdFItd/openapi.json
