# Montana Contractor License Lookup & Leads Scraper (DLI) (`scrapebench/montana-contractor-license-lookup`) Actor

Montana construction contractor licences from the Department of Labor & Industry: business name, owner, phone, city, state, ZIP, licence number, status and expiry. Export the list or look up a licence number.

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

## Pricing

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

## Montana Contractor License Lookup & Leads Scraper (DLI)

### Pain points

- DLI's own licensee lookup asks for a picture-puzzle verification before it answers, and its downloadable list leaves the phone number out (the board's page says so).
- The Accela record search that also lists the licences stops at '150+' results per search and shows 15 rows a page.
- The licence holder's name and phone are not in the search results: each licence's own page has to be opened to see them.

### What we solve

- Every Construction Contractor Licence in DLI's Accela record search, read by licence-number range so no search hits the 150-result cap (11,878 counted in the older number ranges alone on November 6, 2026).
- One clean table: licence number, business name, the owner's name where DLI lists one, phone, city, state and ZIP, the street address where the licence carries one, status and expiry date.
- Looks up licence numbers live on DLI's record search; business names are matched in the stored copy.

### Summary

Montana Department of Labor & Industry Construction Contractor Licences in one dataset: general and trade contractors alike, including the out-of-state firms licensed to work in Montana. Each row has the licence number, the business name, the owner's name on licences issued since DLI moved to its Accela system, the phone DLI lists, city, state and ZIP, the street address where the licence carries one, the status and the expiry date. Exports read a stored copy refreshed from DLI's record search (its date is in the run log); licence-number lookups search DLI live. Pay only per licence returned.

### Who it's for

- Building-material suppliers, lumber yards and equipment dealers selling to Montana contractors
- Insurers, bonding agents and lenders reaching licensed contractors by phone
- General contractors and property managers checking a subcontractor's Montana licence and expiry
- Out-of-state firms sizing the Montana contractor market

### 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
{
  "statuses": [
    "Active"
  ],
  "maxResults": 500
}
```

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

```json
{
  "mode": "lookup",
  "queries": [
    "CCP-CCL-LIC-0318374",
    "0318361"
  ],
  "maxResults": 20
}
```

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

### What you get

One row per record:

| Field | Description |
|---|---|
| `license_number` | Licence number as DLI prints it (CCP-CCL-LIC-0318374); listing_id holds the same |
| `business_name` | The licensed business; name holds the same |
| `person_name` | The owner or qualifying person, on licences issued in DLI's Accela system |
| `phone` | Phone as DLI lists it (business, mobile or home, in that order); phone_e164 in +1XXXXXXXXXX form |
| `status` | Licence status as DLI words it, e.g. Active |
| `expiration_date` | Expiry date (YYYY-MM-DD); licences run two years |
| `address` | Street address, on licences that carry one (mostly those issued since 2026) |
| `city` | City |
| `address_state` | State: many licensed firms are based outside Montana |
| `zip_code` | ZIP code |
| `extras.fax` | Fax number, where listed |
| `extras.record_date` | The date DLI's record was opened |
| `source_url` | The licence's own page on DLI's Accela record search |

Sample:

```json
{
  "license_number": "CCP-CCL-LIC-0318374",
  "business_name": "RIPLEY'S, INC.",
  "person_name": "JEANETTE KAY RIPLEY",
  "phone": "2187702270",
  "phone_e164": "+12187702270",
  "status": "Active",
  "expiration_date": "2028-11-06",
  "city": "ERHARD",
  "address_state": "MN",
  "zip_code": "56534",
  "state": "MT",
  "license_type": "Construction Contractor License",
  "source_url": "https://aca-prod.accela.com/POL/Cap/CapDetail.aspx?Module=BOLB&TabName=BOLB&capID1=26CAP&capID2=00000&capID3=05ANZ&agencyCode=POL"
}
```

### Inputs

| Field | Required | Type | Default | Description |
|---|---|---|---|---|
| `mode` | no | string | `"auto"` | export: no names, just filters; returns the whole matching list. lookup: put licence numbers (CCP-CCL-LIC-0318374, or its last digits) in 'queries'. auto picks the mode for you. |
| `query` | no | string | — | One of: licence numbers (CCP-CCL-LIC-0318374, or its last digits), to look up live. Kept alongside 'queries' for saved tasks. |
| `queries` | no | array | `[]` | One of: licence numbers (CCP-CCL-LIC-0318374, or its last digits), to look up live. Several values in one run; combined with 'query'. |
| `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'. |
| `city` | no | string | — | Only listings in this city. Kept alongside 'cities' for saved tasks. |
| `cities` | no | array | `[]` | Only listings in this city. Several values in one run; combined with 'city'. |
| `categories` | no | array | `[]` | Only rows from this licence type (one or more). Available: Construction Contractor. |
| `licenseTypes` | no | array | `[]` | Same filter as 'Licence type', 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 contractor licences** at *$0.004/result* ≈ **$4.00**.

Notices (no match, source unavailable, stale copy) are free.

### Use cases

- Sales lists: every active Montana contractor licence with a phone, filtered by city.
- Renewal campaigns: licences expiring in the next 90 days (Expires on or before).
- Subcontractor checks: confirm a licence number is active and read its expiry date.
- Market sizing: count licensed contractors by city or by home state.

### Why this actor

- The phone number that DLI's downloadable list leaves out (on 20 of 22 licences read on 2026-11-06).
- No picture puzzle and no 150-result cap: the whole register in one export.
- Filters DLI lacks: status, city and expiry date, each taking a list.
- Pay per licence; notices are free.

### Limitations & updates

Covers Construction Contractor Licences in the Montana Department of Labor & Industry's Accela record search, every status. Electrical, plumbing and other DLI boards are not included. A street address is on licences issued since the 2026 move to Accela only; every licence carries a city, state and ZIP. Exports come from a stored copy; live lookups take licence numbers. One run returns at most 100,000 rows.

### FAQ

**Where does the data come from?**

The Montana Department of Labor & Industry's Accela Citizen Access record search (aca-prod.accela.com/POL), where DLI keeps its Construction Contractor Licences. Exports come from a stored copy made by searching every licence-number range and opening each licence's own page for the holder and phone; the run log gives the copy's date. Licence-number lookups search DLI live.

**Does it cover electricians and plumbers?**

No. Electrical and plumbing licences are issued by other DLI boards and are not records in this search (their licence types answer no results). This actor covers Construction Contractor Licences.

**Is there a street address?**

On licences that carry one, mostly those issued since DLI's 2026 move to Accela. Older licences list a city, state and ZIP with the phone; DLI's own page prints their street as blank.

**Can I look up a business by name?**

Yes, in lookup mode a name is matched against the stored copy (contained in the business name). DLI's record search does not search by the licence holder's name, so only licence numbers are searched live. A name lookup adds a free notice saying the match came from the stored copy.

**How current is it?**

Exports come from a stored copy of DLI's register; the run log states its date, and a copy older than 45 days adds a free notice saying so. Licence-number lookups are live.

**How am I charged?**

One event per licence 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 Montana Contractor License Lookup & Leads Scraper (DLI)](https://scrapebench.dev/guides/how-to-montana-contractor-license-lookup/)
- **Use case:** [Montana Active Contractor Licences (DLI)](https://scrapebench.dev/use-cases/montana-active-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/montana-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:

> "Look up Montana contractor licence CCP-CCL-LIC-0318361 at the Department of Labor & Industry: who holds it, its status and expiry, and the phone number."

That is a lookup with one licence number (run live 2026-11-06 through the adapter: JUNIPER DESIGN HOMES, Active until 2028-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 Montana Department of Labor & Industry (DLI), Construction Contractor Registration program 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 Montana Department of Labor & Industry (DLI), Construction Contractor Registration program. 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: put licence numbers (CCP-CCL-LIC-0318374, or its last digits) in 'queries'. auto picks the mode for you.

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

One of: licence numbers (CCP-CCL-LIC-0318374, or its last digits), to look up live. Kept alongside 'queries' for saved tasks.

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

One of: licence numbers (CCP-CCL-LIC-0318374, or its last digits), to look up live. Several values in one run; combined with 'query'.

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

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

Only listings in this city. Kept alongside 'cities' for saved tasks.

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

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

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

Only rows from this licence type (one or more). Available: Construction Contractor.

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

Same filter as 'Licence type', 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": [],
  "statuses": [],
  "cities": [],
  "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/montana-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/montana-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/montana-contractor-license-lookup --silent --output-dataset

```

## MCP server setup

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