Contractor License Leads — Licensed US Contractors
Pricing
from $100.00 / 1,000 lead returneds
Contractor License Leads — Licensed US Contractors
Licensed US contractor leads — name, phone, specialty/trade and license status from official state open-data sources. For building-supply, SaaS and B2B sales targeting active contractors.
Pricing
from $100.00 / 1,000 lead returneds
Rating
0.0
(0)
Developer
Muhammad Afzal
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
21 hours ago
Last modified
Categories
Share
Extract licensed US contractor records from official state open-data sources and convert them into structured construction B2B lead data. Each run returns lead records with business name, principal, phone, address, specialty/trade, license type, license status, and license dates, filterable by state, city, and trade specialty (roofing, electrical, plumbing, HVAC, general contractors).
Built for building-supply, SaaS and B2B sales teams targeting active contractors, contractor insurance & bonding lead generation, construction field-service software customer acquisition, fuel & fleet services targeting contractor fleets, and recruiting/staffing for construction trades.
Supported states
| State | Source | Method |
|---|---|---|
| WA | Washington L&I "Verify a Contractor" | Playwright (JS-rendered search) |
| CA | CSLB CheckLicenseII | Playwright (ZIP-prefix search + detail pages) |
| TX | TDLR LicenseSearch | Cheerio (classic ASP form POST) |
More states are added over time as adapters are built. Pass an empty states array to scrape all supported states in one run.
Use cases
- Building-material and equipment suppliers targeting licensed contractors.
- Contractor insurance and bonding lead generation.
- Construction and field-service software customer acquisition.
- Fuel and fleet services targeting contractor fleets.
- Recruiting and staffing for construction trades.
- B2B sales outreach to licensed contractors by specialty and location.
Input parameters
| Field | Type | Default | Description |
|---|---|---|---|
states | array | ["WA"] | 2-letter state codes. Empty = all supported states. |
active_only | boolean | true | Only currently active contractor licenses. |
cities | array | [] | Optional city filter (case-insensitive). |
specialties | array | [] | Trade keyword filter (roofing, electrical, plumbing, HVAC, general). |
max_per_state | integer | 1000 | Max leads per state. Use 50 for a quick test. |
include_raw | boolean | false | Attach the raw source record to each lead. |
Output fields
| Field | Type | Description |
|---|---|---|
business_name | string | Licensed business or contractor name. |
business_type | string|null | Entity type (LLC, Corporation, etc.) when published. |
principal_name | string|null | Qualifying individual / owner, when published. |
phone | string|null | Business phone number. |
address | string|null | Full street address. |
city | string|null | City parsed from the source address. |
region | string|null | County or region, when available. |
state | string | 2-letter US state code. |
zip | string|null | ZIP code parsed from the source address. |
specialty | string|null | Trade, classification, or specialty description. |
license_number | string | Official state license number. |
license_type | string|null | License class or program label. |
status | string | Normalized: Active, Expired, Suspended, Revoked, Inactive, Canceled. |
effective_date | string|null | ISO 8601 (YYYY-MM-DD). |
expiration_date | string|null | ISO 8601 (YYYY-MM-DD). |
detected_at | string | ISO 8601 scrape timestamp. |
source_url | string | State authority page or API endpoint. |
raw | object|null | Original source record (only when include_raw is enabled). |
Pricing
This Actor is paid per event:
- Actor Start: $0.20 per event (one event per GB of memory, minimum one).
- Lead returned: $0.10 per lead record returned to the dataset.
Example: a run returning 200 leads costs $0.20 (start) + $20.00 (leads) = $20.20.
Architecture
Per-state adapter modules each pick the best source for their state (bulk open-data download vs scraping the search UI) and emit normalized LeadRecords via an async generator. The orchestrator applies client-side filters (active_only, cities, specialties), charges one PPE event per surviving record, and pushes to the dataset.
src/├── main.ts # orchestrator├── types.ts # shared types (LeadRecord, LeadFilters, StateAdapter)├── utils.ts # normalize, charge, filter helpers└── adapters/├── index.ts # state registry├── wa.ts # WA L&I (Playwright)├── ca.ts # CA CSLB (Playwright)└── tx.ts # TX TDLR (Cheerio)
To add a state, create src/adapters/xx.ts exporting an adapter object and add it to the registry in src/adapters/index.ts.
Example input
Quick test (50 WA leads):
{ "states": ["WA"], "max_per_state": 50 }
HVAC contractors across all supported states:
{ "states": [], "specialties": ["HVAC", "air conditioning"], "active_only": true, "max_per_state": 500 }
Run locally
npm installnpm run dev # or: npm run build && npm start
Deploy
apify loginapify push -f -w 120
First publish gotcha: the first time you publish, Apify returns a
store-terms-not-acceptederror. Open the Apify Console → your actor → Publication and accept the Store Terms once manually. After that, all future pushes work without this step.