Use case
Find Minnesota Roofing Contractors with Enforcement Actions
Screen Minnesota residential roofing contractors against DLI's own roster and surface only the licences carrying an enforcement action - revoked, suspended or disciplined.
Say you handle claims for a regional insurer and a hailstorm has just gone through the Twin Cities suburbs. Within a week, assignment-of-benefits paperwork starts arriving from roofing companies you have never heard of. Storm-chasing outfits appear fast, work under names that change, and some of them are operating on a licence Minnesota has already revoked. You need to know which names on this week’s pile are carrying a disciplinary flag — before the adjuster schedules the inspection, not after the cheque clears.
The manual way, and what it costs
Minnesota’s Department of Labor & Industry doesn’t make you scrape a search form for this. It publishes the entire residential-contractor roster as a single nightly export — one CSV, about 12 MB, sitting at a public URL. There is no query interface on that file: you take all of it or none of it.
If you need this once, download it and use a spreadsheet. Open the CSV, filter the name column, filter the enforcement column, done — that is a genuinely reasonable afternoon and it costs nothing.
Where it stops being reasonable is repetition and scale. It is a 12 MB file with Windows-1252 encoding that Excel will cheerfully mangle if you double-click it, roughly two dozen columns of which you want six, and a licence-type field that is useless on its own because every row says “Residential Contractors” — the meaningful part is in a separate subtype column. Doing that dance weekly, during a storm season, for a pile of names that changes every Monday, is the point where a one-line call beats a manual re-import.
The faster way
Minnesota Contractor License Lookup & Leads Scraper (DLI) does the same search once and hands back every row at once.
{
"query": "ROOFING",
"enforcementOnly": true,
"maxResults": 100
}
query is matched two ways: exactly against the licence number, or as a substring of the business
and DBA names. ROOFING therefore sweeps every licensee trading with that word in its name —
which, for storm-chaser screening, is most of them. enforcementOnly: true is the mode that makes
this a screen rather than a directory: it drops every row without DLI’s enforcement flag set, so the
run returns only licensees the department has taken action against. maxResults: 100 sets the
ceiling on what a broad word can bring back, and since the whole roster is fetched once and filtered
in memory, adding a second keyword run costs another call rather than another download.
What comes back
{
"state": "MN",
"license_number": "RR531208",
"business_name": "RASSMUSSEN METAL ROOFING AND CONSTRUCTION INC (dba RMR CONSTRUCTION INC)",
"person_name": null,
"license_type": "Residential Contractors - Residential Roofer Contractor",
"status": "REVOKED",
"issue_date": "06/20/2005",
"expiration_date": "03/31/2008",
"city": "MINNEAPOLIS",
"address": "5536 27TH AVE S",
"zip_code": "55417",
"phone": null,
"enforcement_action": "1",
"renewal_in_progress": null,
"matched_by": "business_name",
"source_url": "https://secure.doli.state.mn.us/ccld/data/MNDLILicRegCertExport_Residential_Contractors.csv"
}
| Field | Example value | Meaning |
|---|---|---|
state | MN | Licensee’s registered state (usually ‘MN’) |
license_number | RR531208 | DLI license number (e.g. BC807688) |
business_name | RASSMUSSEN METAL ROOFING AND CONSTRUCTION INC (dba RMR CONSTRUCTION INC) | Licensed business name (DBA appended when present) |
person_name | — | Individual’s name when the licensee is a person, else null |
license_type | Residential Contractors - Residential Roofer Contractor | License type + subtype (e.g. ‘Residential Contractors - Qualifying Builder’) |
status | REVOKED | License status (e.g. Issued, EXPIRED, REVOKED, SUSPENDED) |
For the claims pile, enforcement_action is the flag that put the row in front of you and status
is what tells you how far it went — REVOKED is a different conversation from a licence that merely
lapsed. business_name is the field to read twice: the DBA is appended in parentheses, which is
precisely how a storm chaser shows up under a name your adjuster doesn’t recognise while holding the
licence you already flagged. license_type confirms the subtype is actually a roofer rather than a
general residential builder who happens to have “roofing” in the trading name.
What you’d do with it
Keep the run as a weekly screening list: match business_name and its DBA against the week’s
assignment paperwork, and route any hit to a manual review before the inspection is scheduled. Store
license_number on the file so the next storm’s paperwork matches on the identifier rather than on
a name that will have changed.
Worth knowing
The query matches names, not licence types. ROOFING finds licensees with that word in their
business or DBA name, and it does not return every roofer licence in the state. On 2026-10-07 that
input filled its 100-row cap, and only 18 of the 100 were roofer contractor licences; 46 were
residential building contractors with “roofing” in the name. If the subtype is what you care about,
leave query empty and use the statewide export instead:
{"licenseSubtype": "roofer", "status": "all", "enforcementOnly": true, "maxResults": 100000}
returned every roofer licence carrying an enforcement flag that day, 35 of them, and 13 of those had
no “roofing” in the name at all. Set status to all on purpose: a statewide export defaults to
active licences, and most enforcement actions sit on revoked or lapsed ones (11 of the 35 were REVOKED).
enforcement_action is a flag, not a case file. It is DLI’s own published marker that an action
exists. There is no case number, no date, no reason and no severity in it — the value is the raw flag
the department publishes. Treat a hit as “go read the department’s record”, not as a finding.
Residential contractors only. This roster is DLI’s residential-contractor list — building contractors, remodelers, roofers, installers and related certificates. Electrical, plumbing and other trade boards are not in it.
It is a nightly snapshot, not a live registry. Results reflect the last published export, so an
action recorded this morning may not appear until tomorrow’s file. Bond and insurance details are not
part of this roster and are returned null.
Run it yourself: How to run Minnesota Contractor License Lookup & Leads Scraper (DLI) walks the whole thing step by step.
Screening the same storm-chasing crews one state east, Verify a Michigan Contractor License by Number covers LARA’s registry. If the contractor turns out to be licensed somewhere else entirely, Multi-State Contractor & Trade License Lookup checks WA, OR, TX and CT from one input.
Last updated 2026-10-07