# Minnesota DLI Professional License Scraper (`haketa/minnesota-dli-license-scraper`) Actor

Minnesota DLI license scraper & API: search Department of Labor and Industry licenses and export license number, type, status, holder, business, address and expiry. License verification, compliance and B2B lead generation — fast, no login.

- **URL**: https://apify.com/haketa/minnesota-dli-license-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Automation, Developer tools, Lead generation
- **Features:** Limited permissions
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 results

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

## Minnesota DLI License Scraper — Contractor, Electrician, Plumber, Boiler & Bond License Data

> **The fastest, most comprehensive Minnesota Department of Labor and Industry (DLI) license data extractor on Apify.** This **Minnesota DLI scraper** extracts the official regulant database — residential building contractors, master and journeyman electricians, plumbers, boiler operators, elevator constructors, high-pressure pipefitters, contractor registrations, and mechanical contractor bond holders — into clean, normalized records ready for compliance, B2B lead generation, trades recruiting, credentialing, and market intelligence across Minneapolis, Saint Paul, Rochester, Duluth, Bloomington, Brooklyn Park, Plymouth, Woodbury, Lakeville, St. Cloud, and every other Minnesota market. No login, no coding, no captcha.

Export to **JSON, CSV, Excel, or API**.

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue)](https://apify.com/haketa/minnesota-dli-license-scraper)
[![Engine: Direct Data Stream](https://img.shields.io/badge/Engine-Direct%20Stream-green)]()
[![No Auth Required](https://img.shields.io/badge/Authentication-None%20Required-success)]()
[![License Categories](https://img.shields.io/badge/Categories-8%20Regulant%20Types-purple)]()
[![Deep Pagination](https://img.shields.io/badge/Pagination-1%2C000%2B%20Unlocked-brightgreen)]()
[![State Coverage](https://img.shields.io/badge/State-Minnesota%20\(Statewide\)-red)]()

> **Built for:** construction and building material suppliers building B2B lead lists, general contractors running subcontractor credentialing and compliance checks, trades staffing recruiters sourcing certified journeymen, underwriters evaluating commercial surety and liability risk, and market researchers tracking Minnesota construction growth.

***

### ⚡ At a glance

| Feature | Details |
|---|---|
| **Data Source** | Minnesota Department of Labor and Industry (DLI) Official Regulant Database |
| **Geographic Scope** | All 87 Minnesota counties (Twin Cities metro, Rochester, Duluth, St. Cloud, statewide) |
| **Trade Categories** | Electrical, Plumbing, Residential Contractors, Registrations, Mechanical Bonds, Boiler, High-Pressure Piping, Elevator |
| **Available Records** | 260,000+ active & historical licensed professionals and registered businesses |
| **Key Output Fields** | License #, legal name, DBA, trade subtype, entity type, status, issue date, expiration date, street address, city, state, ZIP, county, phone, bond info |
| **Export Formats** | JSON, CSV, Excel (XLSX), XML, HTML table, webhook & REST API |
| **Max Capacity** | Scalable from 50 test records to 1,000+ or full state extraction (260K+ rows) |
| **Execution Speed** | ~100 records in <10 seconds; full snapshots in under 2 minutes |
| **Proxy Requirements** | None required; optional Apify Proxy supported |

***

### 🔎 Why scrape Minnesota DLI license data?

The **Minnesota Department of Labor and Industry (DLI)** is the primary regulatory agency overseeing construction trades, mechanical contractors, electrical systems, and building safety across Minnesota. DLI maintains comprehensive credential records for more than **260,000 professional tradespeople, specialty contractors, and registered business entities**.

Manually navigating public portals or parsing massive tabular files creates significant operational friction for sales and operations teams:

- **B2B lead generation & sales prospecting:** Construction material wholesalers, equipment rental providers, software vendors, and commercial lenders can pinpoint active licensed general contractors, master electricians, and plumbing businesses across specific Minnesota ZIP codes or counties.
- **Subcontractor compliance & vendor onboarding:** General contractors (GCs) and project managers can automate credential verification, ensuring that every trade partner on site possesses an active, unexpired license without disciplinary actions.
- **Insurance underwriting & surety bonding:** Commercial lines carriers, MGAs, and surety bond agents can cross-reference applicant data against official license status, effective dates, bond carrier information, and historical enforcement notices.
- **Trades recruiting & talent acquisition:** Staffing agencies and industrial employers can identify certified journeymen and master tradespeople holding specialized credentials (e.g., high-pressure pipefitting, boiler operation, elevator construction).
- **Market intelligence & competitive analysis:** Private equity firms and building product manufacturers can map trade contractor concentration, market share, and regional licensing velocity across the Upper Midwest.

***

### 🗂️ Covered Minnesota License Categories

This scraper extracts data across all eight statutory DLI licensing categories:

1. **Residential Contractors (`Residential_Contractors`):** Licensed residential building contractors (RBC), residential remodelers (RR), and residential roofers (RS). These are primary entities constructing, repairing, and improving homes throughout Minnesota.
2. **Contractor Registrations (`Contractor_Registrations`):** Unlicensed specialty trade subcontractors registered under Minnesota's statutory contractor registration program.
3. **Electrical (`Electrical`):** Class A and Class B master electricians, journeyman electricians, maintenance electricians, power limited technicians, and licensed electrical contractor businesses. Represents over 110,000 records statewide.
4. **Plumbing (`Plumbing`):** Master plumbers, journeyman plumbers, plumbing contractors, medical gas piping certifiers, and registered plumbing apprentices.
5. **Mechanical Contractor Bond (`Mechanical_Contractor_Bond`):** Heating, ventilation, air conditioning (HVAC), sheet metal, refrigeration, and environmental systems contractors holding statutory mechanical surety bonds with the state.
6. **Boiler Operations & Inspection (`Boiler`):** Chief engineers, 1st class engineers, 2nd class engineers, special boiler engineers, and certified boiler historical operators overseeing high and low pressure boilers.
7. **High Pressure Piping (`High_Pressure_Piping`):** Pipefitter journeymen, pipefitter contractors, and certified high-pressure piping specialists working on pressurized industrial process piping systems.
8. **Elevator Constructors (`Elevator`):** Master elevator constructors, journeyman elevator constructors, and elevator contractor businesses servicing commercial conveying systems.

***

### ✨ What this Minnesota DLI scraper does

This actor delivers an end-to-end data pipeline that extracts, validates, and normalizes Minnesota trades licensing records into structured datasets:

- ✅ **Full category coverage:** Access all 8 primary regulant categories — `Electrical`, `Plumbing`, `Residential_Contractors`, `Contractor_Registrations`, `Mechanical_Contractor_Bond`, `Boiler`, `High_Pressure_Piping`, and `Elevator`.
- ✅ **Flexible extraction modes:** Pick specific trade categories for targeted searches, or toggle full-state mode to process the comprehensive statewide dataset in a single run.
- ✅ **Clean entity classification:** Automatically categorizes entries into business entities versus individual license holders based on official regulatory attributes.
- ✅ **Deep 1,000+ record pagination:** Request anywhere from a quick 100-record sample to 1,000+ entries or full statewide dumps without artificial caps.
- ✅ **Standardized data hygiene:** Cleanly formats telephone numbers, normalizes dates into standardized ISO stamps, strips padding from postal codes, and resolves DBA trade names.
- ✅ **Status filtering:** Instantly filter for currently active (`issued`) licenses or include expired, suspended, and historical records for audit trails.
- ✅ **Developer-friendly integration:** Native Apify dataset export to JSON, CSV, and Excel, with webhook triggers and REST API support.

***

### 📊 Extracted Data Fields

The scraper extracts all regulatory fields and maps them into a consistent, developer-ready schema:

#### 🏢 Licensing & Classification Fields

| Field | Coverage | Description |
|---|---|---|
| `licenseNumber` | 🟢 High (100%) | Official state license or registration number (e.g., `BC654321`) |
| `name` | 🟢 High (100%) | Primary business or individual licensee name |
| `licenseType` | 🟢 High (100%) | High-level regulatory trade category (e.g., `Residential Contractors`) |
| `licenseSubtype` | 🟢 High (98%) | Specific credential or craft classification (e.g., `Residential Building Contractor`) |
| `sourceCategory` | 🟢 High (100%) | Standardized internal category key |
| `entityType` | 🟢 High (100%) | Entity classification: `Business` or `Individual` |
| `businessName` | 🟡 Conditional | Clean business entity name when license is corporate |
| `individualName` | 🟡 Conditional | Formatted personal name when license is held individually |
| `dba` | 🟡 Conditional | Doing Business As / trade name registered with DLI |
| `responsibleIndividual` | 🟡 Conditional | Qualifying licensee or designated responsible managing officer |

#### 📅 Status & Compliance Fields

| Field | Coverage | Description |
|---|---|---|
| `status` | 🟢 High (100%) | Current licensing status (`Issued`, `Expired`, `Suspended`, `Revoked`) |
| `issueDate` | 🟢 High (99%) | Date the credential was originally issued (`YYYY-MM-DD`) |
| `expirationDate` | 🟢 High (99%) | Current expiration date (`YYYY-MM-DD`) |
| `enforcementAction` | 🟢 High (100%) | Indicates whether formal enforcement or disciplinary action is noted (`true`/`false`) |
| `renewalInProgress` | 🟢 High (100%) | Flags whether a license renewal application is currently pending (`true`/`false`) |
| `bondAmount` | 🟡 Conditional | Stated surety or mechanical bond amount where required by statute |
| `bondCompany` | 🟡 Conditional | Underwriting surety company holding the active compliance bond |

#### 📍 Location & Contact Fields

| Field | Coverage | Description |
|---|---|---|
| `address` | 🟢 High (98%) | Primary mailing or business physical street address |
| `city` | 🟢 High (99%) | City or municipality name |
| `state` | 🟢 High (100%) | Two-letter state code (`MN` or out-of-state licensee origin) |
| `zipCode` | 🟢 High (99%) | Standardized 5-digit US postal ZIP code |
| `county` | 🟡 Conditional | Minnesota county name corresponding to the licensee address |
| `phone` | 🟡 Conditional (55-65%) | Primary telephone contact number provided on the license filing |
| `email` | ⚪ Rare (<5%) | Email address when voluntarily supplied on public public filings |
| `scrapedAt` | 🟢 High (100%) | ISO 8601 UTC timestamp of record extraction |

***

### ⚙️ Input Parameters

Configure your crawl using intuitive settings in the Apify Console or pass JSON parameters via API:

```json
{
  "categories": [
    "Residential_Contractors",
    "Electrical",
    "Plumbing"
  ],
  "useZip": false,
  "statusFilter": "issued",
  "maxRecords": 500,
  "requestDelay": 200
}
```

| Parameter | Type | Default | Description |
|---|---|---|---|
| `categories` | `array` | `["Mechanical_Contractor_Bond", "High_Pressure_Piping"]` | Select one or more trade categories to extract. Leave empty to process all categories. |
| `useZip` | `boolean` | `false` | Enable to download the full statewide snapshot in one pass. Ideal for comprehensive bulk exports. |
| `statusFilter` | `string` | `"all"` | Filter by license standing: `"issued"` for active licenses only, or `"all"` for full historical records. |
| `maxRecords` | `integer` | `100` (prefill), `0` (default) | Maximum records to output across selected categories. Set to `0` for unlimited extraction. |
| `requestDelay` | `integer` | `200` | Optional millisecond pause between category streams to balance network throughput. |
| `proxyConfiguration` | `object` | `{"useApifyProxy": false}` | Optional proxy settings. Public streams operate reliably without proxies. |

***

### 📦 Sample Output

Every record is returned as structured, normalized JSON:

```json
{
  "licenseNumber": "BC789123",
  "name": "NORTH STAR CRAFTSMEN LLC",
  "businessName": "NORTH STAR CRAFTSMEN LLC",
  "individualName": null,
  "dba": "NORTH STAR ROOFING & EXTERIORS",
  "responsibleIndividual": "JOHN R LARSON",
  "licenseType": "Residential Contractors",
  "licenseSubtype": "Residential Building Contractor",
  "sourceCategory": "Residential_Contractors",
  "entityType": "Business",
  "status": "Issued",
  "issueDate": "2018-04-12",
  "expirationDate": "2026-03-31",
  "enforcementAction": false,
  "renewalInProgress": false,
  "address": "1420 INDUSTRIAL BLVD STE 200",
  "city": "MINNEAPOLIS",
  "state": "MN",
  "zipCode": "55413",
  "county": "Hennepin",
  "phone": "(612) 555-0192",
  "email": null,
  "bondAmount": "$15,000",
  "bondCompany": "TRAVELERS CASUALTY & SURETY CO",
  "scrapedAt": "2026-11-10T12:00:00.000Z"
}
```

***

### 💡 Practical Use Cases

#### 1. B2B Sales Prospecting for Building Supplies

Commercial suppliers selling lumber, electrical panels, plumbing fixtures, or roofing materials can filter by category (e.g., `Residential_Contractors` or `Electrical`) and target active, licensed business entities throughout Minneapolis, St. Paul, and surrounding metros. Export contacts with phone numbers and street addresses to feed CRM outreach campaigns.

#### 2. General Contractor Subcontractor Credentialing

Before dispatching specialty trades to active job sites, commercial general contractors can cross-reference trade partners against official DLI records. Verify whether their license is currently `Issued`, confirm that the license subtype matches the contracted scope of work, and ensure that expiration dates extend beyond project milestones.

#### 3. Surety & Commercial Insurance Lead Generation

Surety bond brokers and commercial P\&C agencies can track firms registered under `Mechanical_Contractor_Bond` or `Residential_Contractors` whose licenses approach statutory renewal deadlines. Proactively reach out to offer competitive commercial auto, general liability, and bonding solutions.

#### 4. Direct Mail Marketing to Licensed Trades

Direct mail campaigns targeting trades professionals achieve significantly higher deliverability when verified against state licensing rosters. Pull physical addresses for verified businesses and eliminate invalid leads before printing postcards, catalogs, or equipment promotions.

#### 5. Regional Economic Analysis & Roll-Up Strategy

Private equity investors and corporate acquirers pursuing HVAC, electrical, or plumbing roll-ups in the Upper Midwest can gauge market density, corporate age (based on `issueDate`), and geographic clustering of independent service contractors.

***

### 🛠️ Data Normalization & Quality Assurance

Raw regulatory rosters frequently suffer from legacy formatting artifacts. This Actor applies extensive data hygiene filters on every record:

- **Entity Separation:** Analyzes regulatory classification headers to accurately populate `businessName` versus `individualName`.
- **Phone Number Cleansing:** Removes extraneous alpha characters, strips non-numeric noise, and standardizes numbers into standard 10-digit formats with area codes.
- **Address & Postal Standardization:** Trims redundant zero-padded ZIP+4 extensions (e.g., `55401-0000` is cleaned to `55401`) and capitalizes municipality names uniformly.
- **Date Normalization:** Parses varied US date stamps (`MM/DD/YYYY`) into standard ISO format (`YYYY-MM-DD`) for direct database ingest and temporal filtering.
- **Enforcement Flagging:** Booleans `enforcementAction` and `renewalInProgress` are parsed into true booleans rather than ambiguous state codes.

***

### 🚀 How to Run via Apify API

Trigger the actor programmatically from your Node.js, Python, or shell workflows:

#### Node.js (Apify Client)

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const run = await client.actor('haketa/minnesota-dli-license-scraper').call({
    categories: ['Residential_Contractors', 'Plumbing'],
    statusFilter: 'issued',
    maxRecords: 1000,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Successfully scraped ${items.length} active Minnesota licenses.`);
```

#### Python (Apify Client)

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.getenv('APIFY_TOKEN'))

run = client.actor('haketa/minnesota-dli-license-scraper').call(run_input={
    'categories': ['Electrical', 'Mechanical_Contractor_Bond'],
    'statusFilter': 'issued',
    'maxRecords': 1000,
})

dataset_items = client.dataset(run['defaultDatasetId']).list_items().items
print(f'Retrieved {len(dataset_items)} Minnesota licensing records.')
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/haketa~minnesota-dli-license-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "categories": ["Residential_Contractors"],
    "statusFilter": "issued",
    "maxRecords": 500
  }'
```

***

### ❓ Frequently Asked Questions

**How many records are available in total?**
The entire Minnesota DLI regulant registry contains over 260,000 records across all 8 trade categories. The Electrical category alone represents over 100,000 individual and business entries.

**Can I request 1,000+ or unlimited records?**
Yes. You can set `maxRecords` to `1000`, `5000`, `50000`, or `0` (unlimited). Setting `maxRecords: 0` instructs the scraper to collect all matching records for your selected categories or full statewide export.

**How fast does the actor run?**
Targeted category runs collecting 100–500 records typically finish in 5 to 15 seconds. Full statewide extractions using `useZip: true` process hundreds of thousands of rows in under two minutes thanks to optimized streaming parsers.

**Are phone numbers and email addresses included?**
Primary business telephone numbers are present on approximately 55% to 65% of records, depending on whether the licensee elected to provide a phone contact upon filing. Email addresses are rarely disclosed in public regulatory exports (<5%).

**Can I run the actor on a recurring schedule?**
Yes. Use Apify Schedules to trigger weekly or monthly runs. This enables you to track license status changes, detect newly issued trade credentials, and identify expiring bonds automatically.

**What formats can I download the results in?**
Datasets can be downloaded directly from the Apify Console or API as JSON, CSV, Microsoft Excel (XLSX), XML, or RSS feeds.

**What is the difference between Residential Contractors and Contractor Registrations?**
Residential Contractors hold a full qualifying builder or remodeler license (such as RBC or RR), requiring insurance, bonding, and exam qualifications. Contractor Registrations cover specialty trade subcontractors that do not require a separate state license but must be registered with DLI.

***

**Can I export directly into Pandas or CSV for data analysis?**
Yes. You can fetch the raw dataset directly into a Python Pandas DataFrame using `pd.read_csv("https://api.apify.com/v2/datasets/<DATASET_ID>/items?format=csv")` or by calling the Apify Python client directly.

**How often does the state update licensing information?**
The Minnesota Department of Labor and Industry refreshes its public licensing database continuously. New licenses, renewals, and status modifications are reflected in live daily snapshots.

**Are disciplinary records and enforcement actions detailed?**
The scraper provides a boolean flag (`enforcementAction`) indicating whether formal administrative or disciplinary enforcement exists on the record. For full enforcement order texts, licensees can be cross-referenced with public DLI dockets.

**Can I target specific trade subtypes like Journeyman Electrician or Master Plumber?**
Yes. While the scraper pulls across the requested high-level category (e.g., `Electrical`), every row retains its granular `licenseSubtype` (such as `Class A Master Electrician`, `Class A Journeyman`, or `Maintenance Electrician`). You can filter downstream or in Apify dataset views.

### 🔗 Related State Licensing Scrapers

Building multi-state contractor databases? Explore these complementary scrapers from the same publisher:

- [Arizona ROC Contractor License Scraper](https://apify.com/haketa/az-roc-contractor-license-scraper) — Official Arizona Registrar of Contractors database
- [Washington L\&I Contractor License Scraper](https://apify.com/haketa/washington-li-contractor-license-scraper) — Washington State Department of Labor & Industries
- [Virginia DPOR Professional License Scraper](https://apify.com/haketa/virginia-dpor-license-scraper) — Virginia Department of Professional and Occupational Regulation
- [Colorado Professional License Scraper](https://apify.com/haketa/colorado-professional-license-scraper) — Colorado DORA state licensing board
- [Ohio eLicense Scraper](https://apify.com/haketa/ohio-elicense-scraper) — Ohio state professional and trades licensing
- [NC Licensing Board for General Contractors Scraper](https://apify.com/haketa/nc-licensing-board-for-general-contractors-scraper) — North Carolina general contractor registry

***

***

### 🗺️ Minnesota Geographic & County Coverage

This scraper extracts licensing data across all 87 Minnesota counties and major metropolitan statistical areas (MSAs):

- **Twin Cities Metropolitan Area:** Hennepin County (Minneapolis, Bloomington, Plymouth, Brooklyn Park, Eden Prairie), Ramsey County (Saint Paul, Roseville, Maplewood), Dakota County (Lakeville, Eagan, Burnsville), Anoka County (Coon Rapids, Blaine, Andover), Washington County (Woodbury, Cottage Grove, Stillwater), Carver County (Chanhassen, Chaska), and Scott County (Shakopee, Prior Lake).
- **Central & Northern Minnesota:** Olmsted County (Rochester), St. Louis County (Duluth, Hibbing, Virginia), Stearns County (St. Cloud), Clay County (Moorhead), Crow Wing County (Brainerd), and Beltrami County (Bemidji).
- **Southern & Western Minnesota:** Blue Earth County (Mankato), Winona County (Winona), Nicollet County (North Mankato), Lyon County (Marshall), and Kandiyohi County (Willmar).
- **Out-of-State Reciprocal Licensees:** Regulants based in neighboring states (Wisconsin, Iowa, North Dakota, South Dakota) maintaining registered reciprocal licenses to operate on Minnesota construction projects.

***

### 🔄 Automated Workflows & CRM Integration

Seamlessly integrate scraped Minnesota licensing records into your existing technology stack:

- **HubSpot & Salesforce CRM Sync:** Ingest new general contractors and electrical firms directly into your CRM pipeline with automated enrichment for business name, license status, and phone numbers.
- **Automated Zapier & Make Webhooks:** Configure Apify Webhooks to trigger instantaneous notifications or update Google Sheets whenever a scheduled run finishes.
- **PostgreSQL / BigQuery Data Warehousing:** Pipe clean JSON datasets into relational warehouses to maintain historical time-series datasets of contractor credential renewals and bond statuses.
- **Weekly Compliance Alerts:** Schedule a weekly diff run to spot subcontractors whose licenses have lapsed from `Issued` into `Expired` or `Suspended` status.

### 📋 Changelog

#### Version 1.2 (2026-11)

- **Deep 1,000+ Pagination Unlocked:** Fully uncapped record limits for multi-category and bulk queries, enabling seamless extraction of 1,000 to 260,000+ records.
- **Fast Prefill Optimization:** Streamlined default prefill parameters to deliver a high-signal 100-record mixed sample in <10 seconds.
- **Enhanced Field Normalization:** Upgraded phone number formatting, ISO date parsing, and robust ZIP code trimming across all 8 trade categories.
- **Improved Fault Tolerance:** Hardened streaming parser against corrupted or malformed rows in regulatory snapshots.

#### Version 1.1 (2026-07)

- Added dual ingestion support: individual category streams and full statewide combined archives.
- Automated entity classification into corporate businesses versus individual tradespeople.
- Integrated bond amount and surety company detection for mechanical and contracting bond holders.

#### Version 1.0 (2026-04)

- Initial release with support for all 8 Minnesota DLI trade categories.
- Direct HTTPS streaming engine with zero proxy or browser overhead.

# Changelog

This Actor's version history is a separate document: https://apify.com/haketa/minnesota-dli-license-scraper/changelog.md

# Actor input Schema

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

Pick the license types you want. Each category returns its own set of records — contractors, electricians, plumbers, roofers and more. Leave empty to include every category.

## `useZip` (type: `boolean`):

Turn this on to grab every license category in one combined download. Fastest way to pull the full Minnesota dataset. Overrides the category selection above.

## `statusFilter` (type: `string`):

Choose which records to keep. 'Issued (Active) Only' returns currently active licenses; 'All Statuses' also includes expired, revoked and suspended records.

## `maxRecords` (type: `integer`):

Maximum total records to return across all selected categories. Set 0 for unlimited. A leave-empty run automatically returns a fast ~100-record mixed sample.

## `requestDelay` (type: `integer`):

Pause between category downloads, in milliseconds. Leave as-is unless you want to slow things down.

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

Optional proxy settings. Usually not needed — Minnesota DLI serves these public files directly.

## Actor input object example

```json
{
  "categories": [
    "Mechanical_Contractor_Bond",
    "High_Pressure_Piping"
  ],
  "useZip": false,
  "statusFilter": "all",
  "maxRecords": 100,
  "requestDelay": 200,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

The scraped Minnesota DLI license records. Open to browse, filter and download as CSV, JSON or Excel.

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

Quick table of the most useful fields for each license record.

# 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 = {
    "categories": [
        "Mechanical_Contractor_Bond",
        "High_Pressure_Piping"
    ],
    "maxRecords": 100,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/minnesota-dli-license-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 = {
    "categories": [
        "Mechanical_Contractor_Bond",
        "High_Pressure_Piping",
    ],
    "maxRecords": 100,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/minnesota-dli-license-scraper").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 '{
  "categories": [
    "Mechanical_Contractor_Bond",
    "High_Pressure_Piping"
  ],
  "maxRecords": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call haketa/minnesota-dli-license-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/minnesota-dli-license-scraper"
        }
    }
}
```

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/COapTqXghDM0WNSBq/builds/i7wmOJ1sSCrQkdgel/openapi.json
