Contractor License Scraper
Pricing
from $0.50 / 1,000 results
Contractor License Scraper
Scrapes HVAC, plumbing, electrical, and general contractor license data from state licensing boards.
Pricing
from $0.50 / 1,000 results
Rating
0.0
(0)
Developer
Ledgerfield Data
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Contractor License Scraper turns 26 separate state government license lookups — normally a slow, manual, one-state-at-a-time chore — into a single structured dataset of every actively licensed General Contractor, Electrician, Plumber, and HVAC contractor across Alabama, Arizona, Colorado, Delaware, Iowa, Kentucky, Louisiana, Massachusetts, Maryland, Maine, Minnesota, Missouri, North Carolina, North Dakota, Nebraska, Nevada, New York (NYC), Ohio, Oregon, South Dakota, Tennessee, Texas, Virginia, Wisconsin, West Virginia, and Wyoming. Every record comes straight from a state's own public license-lookup site or open-data portal (no login, no paywall) — this Actor just automates the lookup, page by page, including three states that only render their data through a live browser. Run it on the Apify platform to get scheduled refreshes, instant API/webhook access to results, automatic proxy rotation, and full run monitoring — no server or browser to maintain yourself. Just 7 of the 26 states already add up to over 250,000 individual license records — see the real per-state counts below.
This is an independent, unofficial tool. It is not affiliated with, endorsed by, or operated on behalf of any state government, agency, or board named in this README — it only reads pages those agencies already publish for free, public lookup.
Why use Contractor License Scraper?
Turn newly issued licenses into a live deal-sourcing feed
A state license board is often the first public trace that a new contracting business exists — before it has a website, before it appears in any business directory, before a competitor even notices. Schedule this Actor to run weekly or monthly and diff each pull against the last one, and you get a rolling feed of brand-new market entrants and freshly renewed operators: an early-mover signal most sourcing teams currently pick up by accident (a referral, a permit filing) instead of systematically.
State license boards are also the only reliably up-to-date public registry of every actively licensed contractor in a state — most of these businesses are small, local, and otherwise invisible to standard business databases. Put together, that makes this data useful for:
- PE roll-up sponsors & M&A advisors sourcing acquisition targets in fragmented, high-margin local-service verticals (HVAC, electrical, plumbing, roofing/general contracting) — build a state-by-state target list ranked by license tenure, trade mix, or expiration (a proxy for renewal/attrition risk), and refresh it on a schedule to catch new entrants as they appear.
- Franchise recruiters identifying independent operators who might convert to a franchise banner — including ones too new or small to show up in a paid business database yet.
- Distributors & suppliers (equipment, materials, insurance) building a prospect list of every licensed contractor in their territory, updated as new licenses are issued.
- Insurers & underwriters verifying a business actually holds an active license before binding a policy or approving a claim.
- Home-services marketplaces & lead-gen platforms vetting whether a contractor signing up is genuinely licensed in their state before listing them.
- Market researchers sizing the number of active operators, license churn, or trade mix by state or county.
The scale, in real numbers
These aren't estimates — they're actual counts pulled from each state's own system: Oregon 102,054 (55,955 general/specialty contractor registrations + 46,099 electrical/plumbing licenses, two separate boards) · Maine 69,988 (52,501 electricians + 17,487 plumbers) · West Virginia 46,414 (34,776 electricians + 6,127 HVAC technicians + 5,511 plumbers) · Iowa 18,307 (general contractor registrations alone, before its separate electrical board) · North Dakota 8,865 (plumbing board alone, before its separate electrical and GC-registration boards) · South Dakota 2,818 · Wyoming 1,864. That's already over 250,000 records across just 7 of the 26 states — and it doesn't include the larger bulk-file states (Texas, Minnesota, Virginia, Alabama) or the several states with their own dedicated Socrata/open-data APIs (Colorado, New York).
Why not just check each state site yourself?
Because it doesn't scale past one state. Twenty-six boards means twenty-six different search forms, column layouts, and pagination styles — some run on ASP.NET WebForms from the 2000s, some on Salesforce Lightning, some publish clean open-data APIs, and a few only expose their roster as a static PDF. Three of them (Massachusetts, Missouri, Wisconsin) only render their data through a JavaScript-heavy portal that a plain HTTP request can't read at all, so a simple "view page source" approach silently returns nothing. Building and maintaining that yourself — across 26 government systems that each redesign on their own schedule — is realistically a multi-week engineering project, then an ongoing maintenance burden. This Actor already did that work and gets fixed centrally when a state changes something; you get one consistent schema across all of them instead of the upkeep.
How to use Contractor License Scraper
- Click Try for free (or Run) on this Actor's page.
- In the Input tab, pick which state(s) to pull from the
stateslist. - Optionally narrow the results with a
tradeTypeFilterorstatusFilter, and setmaxItemsPerStateto cap how many records to pull per state. - Click Start and watch the run log — each state logs how many records it found.
- When the run finishes, open the Output tab to preview, or export the dataset as JSON, CSV, Excel, or HTML.
No coding is required to run it from the Console; developers can also call it via the Apify API or SDKs to integrate results into a CRM, spreadsheet, or data warehouse.
Input
All fields are optional except states. See the Input tab for the full form, or pass JSON
directly:
{"states": ["OR", "IA", "WY"],"tradeTypeFilter": [],"statusFilter": ["Active"],"maxItemsPerState": 10000}
- states — which state boards to query (see the Data table below for the full list).
- tradeTypeFilter — restrict to
GC,ELECTRICAL,PLUMBING, and/orHVAC. Leave empty to include every trade each state's scraper supports. - statusFilter — restrict to specific statuses (values vary by state, e.g.
Active,Expired). Leave empty for all. - maxItemsPerState — upper bound on records pulled per state per run (default
10000).
Output
Each result is one license record, pushed to the dataset in real time as each state finishes. Example item:
{"state": "OR","licenseNumber": "211290","licenseeName": "ACE CONSTRUCTION & MECHANICAL INC","businessName": "ACE CONSTRUCTION & MECHANICAL INC","tradeType": "GC","licenseClass": "Residential General Contractor","status": "Active","city": "TUALATIN","county": "Washington","address": "18840 SW BOONES FERRY RD # 216","issueDate": "2016-07-13","expirationDate": "2028-07-13","disciplinaryFlag": false,"sourceUrl": "https://data.oregon.gov/resource/g77e-6bhs.json","scrapedAt": "2026-07-11T14:00:22.377Z"}
You can download the dataset in various formats such as JSON, HTML, CSV, or Excel from the Output tab, or pull it programmatically via the Dataset API.
Data table
| Field | Description |
|---|---|
state | Two-letter state postal code |
licenseNumber | State-issued license/registration number (or the state's closest equivalent identifier) |
licenseeName | Name on the license record |
businessName | Business/DBA name, when the state exposes one separately from the licensee name |
tradeType | GC, ELECTRICAL, PLUMBING, or HVAC |
licenseClass | License category or class (e.g. Master Electrician, Journeyman Plumber, Residential General Contractor) |
status | Active, Expired, or another state-specific status label |
city / county | Business location, where published |
address | Street address, where published |
issueDate / expirationDate | ISO YYYY-MM-DD dates, where published |
disciplinaryFlag | true when the state's own data marks the license as suspended, conditioned, surrendered, or revoked |
sourceUrl | The exact page/API endpoint the record was read from |
scrapedAt | UTC timestamp the record was collected |
States covered: AL, AZ, CO, DE, IA, KY, LA, MA, MD, ME, MN, MO, NC, ND, NE, NV, NY, OH, OR, SD, TN, TX, VA, WI, WV, WY. Some states only license a subset of the 4 trades at the state level (e.g. Wyoming licenses electricians only; several states have no state-level GC or HVAC license at all) — see each state's entry in the Input tab for exactly which trades it covers.
How much does it cost to scrape state contractor license data?
This Actor runs on Pay Per Event pricing: $2.00 per 1,000 results, plus a small $0.02
flat fee per run — that's the whole bill. Platform compute costs are included in that price, not
billed separately, so the number you see before you run it is the number you pay; three of the
twenty-six states (MA, MO, WI) drive a real headless browser under the hood and cost more to run
than the other twenty-three, but that's absorbed into the flat per-result price rather than passed
through as a variable line item. A default run (a few thousand records per state) costs a few
dollars; pulling a full state's roster (e.g. Oregon's 100,000+ combined records) costs roughly the
same as a few cups of coffee. Apify Store subscribers on paid plans get this Actor's price
automatically discounted — up to 75% off at the top tier. Apify's free tier is normally enough to
try every state at a modest maxItemsPerState.
Tips for scraping state contractor license boards efficiently
- Start with a small
maxItemsPerState(e.g. 50) to sanity-check a state before committing to a full pull. - Six states (AL, AZ, MN, ME, TX, VA) publish their roster as one bulk file rather than a
paginated API —
maxItemsPerStatestill limits what's pushed to the dataset, but the Actor downloads the entire file first regardless of that cap, since there's no way to ask these sources for fewer rows. Maine alone is a ~21MB / 70,000-row combined download every time. Expect these six to take longer and use more bandwidth than a smallmaxItemsPerStatewould suggest, even when you only end up with a handful of records. - Run the plain-HTTP states separately from the three browser-driven states (MA, MO, WI) if you want faster turnaround — the plain-HTTP states finish in seconds, while the browser-driven states take longer per record (pricing is the same flat rate either way, this only affects run time).
- Use
tradeTypeFilterto pull just the trade you care about (e.g.["ELECTRICAL"]) instead of every trade a state's scraper supports. - Use
statusFilter: [](empty) to pull every status the state publishes, not just Active. - Schedule recurring runs (daily/weekly) via Apify Scheduler
to track new licenses and renewals over time — pair with a dedupe step on
licenseNumberif you want a rolling incremental feed.
FAQ
Is this legal? This Actor only reads pages state agencies already publish for free, public lookup — the same pages a person could browse and read by hand. It does not create accounts, submit forms with personal data, or bypass any login, paywall, or CAPTCHA. You're responsible for using the output in line with each state's terms of use and applicable law.
Why do some states have fewer fields than others? Each state publishes a different amount of
detail — some list a full street address, others only a county; some expose separate business and
licensee names, others only one. The Actor never invents a value; a missing field is null.
Why does disciplinaryFlag say false for most states? Only a few states expose a
disciplinary/enforcement-action field on their public license-lookup pages. It's kept in the
schema for every state so a future update can populate it wherever a state adds one.
A state stopped returning data / a site changed. State sites occasionally redesign or move. Please open an issue on this Actor's Issues tab with the state code and what you're seeing, and it'll get investigated.
Can you add another state, or build a custom feed for my exact use case? Yes — reach out via the Issues tab or Apify's contact options to discuss a custom build (additional states, extra fields, dedupe/enrichment, or delivery straight into a CRM).